微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

详解webpack与SPA实践之开发环境搭建

目前,公司前端项目开发技术栈基本改造为使用gulp进行自动化构建,webpack进行项目模块化依赖管理,Vue+ Vuex + Vue-Router作为项目组件化开发框架,为了更深入的理解、使用当前技术栈并与读者分享、交流,计划推出一系列相关学习与实践文章。本篇为开篇,主要讲述如何使用webpack搭建开发环境。

项目初始化

以你喜欢的任意方式,创建项目根目录,如:

rush:bash;"> mkdir vue-hello

初始化包模块管理文件

进入项目根目录,初始化项目包模块管理文件package.json:

rush:bash;"> npm init

命令台会提示你输入一堆信息,如果你想简单一点,可以添加-y参数,跳过输入步骤,生成认信息:

rush:bash;"> npm init -y

初始化源码目录

在项目根目录下创建源码目录结构,通常源码目录是src或app,个人喜好是使用src:

webpack简述及使用

虽然在本篇文章我们不会对webpack做太过详细的介绍,但是依然希望能帮助读者对webpack拥有更清晰的了解,webpack是什么?

webpack is a tool to build JavaScript modules in your application

webpack是一个帮助你的应用构建JavaScript模块的工具。

接下来,我们介绍几个知识点帮助理解webpack:模块化,webpack原理及其与grunt和gulp的比较。

模块化

模块化 指解决一个复杂问题时自顶向下逐层把系统划分成若干模块的过程。

模块是一个可组合、分解和更换的单元,将一个系统分解成若干模块,单元;大家遵循一定的规范,各司其职,各自开发不同模块;之后可以较低成本的将模块组合起来,构成一个完整的系统,极大方便了团队成员之间的协助开发,产出效率得到有效提升。

WEBPACK原理

webpack是一个帮助你的应用构建JavaScript模块的工具,其本质只能处理JavaScript,那你会疑惑了,不是说使用webpack,可以很方便的在JavaScript代码中引用图片,CSS等资源嘛?是的,这正是webpack的优势,那怎么实现的呢?这就要涉及到webpack中的一个概念:加载器(loader)。

加载器 是作用于应用资源文件的转换器,它们是一系列JavaScript函数,接受资源文件内容做参数,然后返回新的资源(以一个JavaScript模块的形式返回)。

所以,对于webpack,我们明确三点:

  1. 模块:webpack中一切资源文件(JavaScript, 样式, 图片资源等)皆视为模块;
  2. 加载器:webpack通过加载器(JavaScript函数)将其他资源处理(构建)成JavaScript模块;
  3. 管理依赖:webpack在编译模块时,就能分析查找该模块内的依赖,可以很好的处理不同模块间的依赖;

WEBPACK对比GRUNT/GULP

grunt

打开grunt官网,你可以看到最醒目的介绍:The JavaScript Task Runner,还有一个关键字automation – 自动化,其定位是一个JavaScript的自动化构建任务处理器,帮助开发者自动化处理项目的构建流程;

gulp

gulp官网的定义是:Automate and enhance your workflow,自动强化项目构建流程,其与grunt的目标一致,都是帮助开发者自动化处理项目的构建流程,不同的是gulp实现方式是基于流的,即以流的方式处理文件,而grunt是以二进制方式处理文件,gulp使用性能是要强于grunt的;

总结

  1. webpack定位是一个模块化管理工具,而grunt/gulp都是自动化任务流程构建工具;
  2. grunt基于二进制处理文件,gulp基于流式处理文件,效率比grunt更高一些;
  3. webpack强大特性,使得其添加诸多插件可以替代grunt/gulp,但是目前的实践项目中,通常webpack结合gulp或grunt使用(各自处理各自专长的任务);

安装

首先安装webpack,npm或yarn都可以,无甚区别:

rush:bash;"> npm install --save-dev webpack

关于此处的--save和-dev参数做简要说明:

  1. --save是声明将安装依赖添加入package.json文件;
  2. 认地,使用npm安装包模块依赖时,依赖关系存储在在"dependencies"属性对象内,表示项目依赖;
  3. webpack是作为开发环境依赖的,不是作为源码直接调用,所以添加-dev参数,以声明其是开发环境依赖;

webpack配置介绍

实践项目使用webpack完成自动化构建,本地服务调试与热加载,首先在根目录下创建webpack的配置入口文件webpack.config.js,基本内容结构如下:

rush:js;"> var path = require('path');

module.exports = {
context: path.resolve(dirname,'src/'),entry: {
app: './scripts/app.js'
},output: {
filename: '[name].js',path: path.resolve(
dirname,'dist/scripts/')
},module: {
loaders: []
},resolve: {
modules:[],alias: {},extensions: []
},plugins: [],devServer: {}
};

如上,webpack配置文件使用module.exports方式导出配置对象,webpack执行时会认读取项目根目录下webpack.config.js文件,当然可以手动配置指定一个文件作为配置文件,我们不讨论,可以参考webpack文档,接下来对webpack配置内容做简要介绍,如果你对webpack使用比较熟悉,可以跳过此节。

文件处理配置

和webpack文件处理相关的几个配置属性主要有三个:目录上下文信息(context),处理文件入口信息(entry),文件输出信息(output)。

目录上下文信息(context)

设置解析处理文件入口的相对目录,值为一个绝对目录路径认为当前执行目录,通常即项目根目录,在Node中其值与process.cwd()相同,如:

rush:js;"> context: path.resolve(__dirname,

如上即解析为项目根目录下的src目录。

处理文件入口信息(entry)

处理文件入口,值可以是字符串,或数组,或对象,值为字符串或数组时,即输出文件,值为对象,可以输出文件输出文件名称等信息参考文件输出信息(output)。

文件输出信息(output)

此配置声明webpack编译输出文件文件名等信息,如:

rush:js;"> filename: '[name].js',

声明文件名就是模块(chunk)名,对应在entry中定义的入口,你可能还见过[id],[hash],[chunkhash]这些用法,现做简单介绍:

  1. [id]:该值表示webpack编译模块(chunk)的id,通常是一个数字;
  2. [name]:该值表示webpack编译模块(chunk)名,对应entry中定义的入口名或文件名;
  3. [chunkhash]:该值表示webpack编译模块(chunk)hash值,根据模块内容计算出的一个md5值;
  4. [hash]:该值表示webapck编译对象hash值,根据编译对象计算出的md5值;

编译对象,即webpack执行时读取配置后生成一个编译配置对象,包含模块,待编译文件,相对于上次编译的变更文件等诸多信息,需要注意的是该对象在webpack启动读取配置文件后形成,在此次编译过程保持不变。

  1. output.path:定义输出文件所在目录;
  2. output.publicPath:定义输出文件在浏览器访问时的基础相对路径,可以与后文webpack-dev-server一起使用。

webpack加载器与模块

在介绍加载器配置之前,先看看加载器是什么:

Loaders are transformations that are applied on a resource file of your app. They are functions (running in node.js) that take the source of a resource file as the parameter and return the new source.

加载器是作用于应用资源文件的转换器,它们是一系列函数,接受资源文件内容做参数,然后返回新的资源(以一个模块的形式返回)。

webpack

webpack解析文件时使用的加载器都声明在module属性的loaders数组中,可以设置一个或多个加载器。

module.noparse:指定某些文件不需要使用解析,支持传入文件路径或正则表达式;

module.loaders:指定解析文件的加载器模块及各模块解析规则,可以设置以下属性

  1. test: 待解析文件需匹配的规则,通常以文件后缀名称匹配文件
  2. include:待解析文件所处目录;
  3. exclude: 过滤掉的目录;
  4. loader:加载器模块名称
  5. loaders多个加载器;

模块解析规则配置

webpack支持在resolve属性对象中配置模块解析规则,主要有root,modules,alias和extensions属性

resolve.root与resolve.modules

属性设置的是在开发代码中使用require或import加载某模块时,webpack查找该模块所遵循的查找目录范围,如在源代码中存在:

rush:js;"> var utils = require('utils/utils.js');

而root配置如下:

rush:js;"> resolve: { root: [ path.resolve('./src/'),'node_modules' ] }

webpack编译时将自动在项目根目录下的src目录内的utils目录下查找utils.js,若存在,则返回,否则进入node_modules目录内查找utils.js模块。

当然,若未设置resolve.root属性值,则webpack认先从node_modules查找模块,然后在根目录下查找。

注意:resolve.root在webpack v1版本中使用,而在webpack v2 中,使用modules代替,建议使用v2版本,后文也将统一使用modules属性

resolve.alias

alias,有别名的意思,这里的作用是设置其他模块或路径的别名,webpack在解析模块时,将使用配置值替换该别名,如,在未设置alias属性内容时,即resolve.alias认是空对象{}时,我们在代码中引用模块:

rush:js;"> var Vue = require('vue/dist/vue.js'); var TopHeader = require('components/header.js');

webpack在编译代码时,按resolve.modules声明的顺序依次查找对应模块,如按照上一节定义的resolve.modules:

rush:js;"> resolve: { root: [ path.resolve('./src/'),'node_modules' ] }

查找模块时,将首先在src/vue/dist/目录下寻找vue模块,在src/components/目录下查找header.js模块,查找到后返回,否则进入node_modules目录查找。

现在,我们还可以通过resolve.alias为模块或路径声明一个别名,更方便的声明加载模块:

rush:js;"> resolve: { alias: { 'vue$': 'vue/dist/vue.js' components: path.resolve(__dirname,'src/components/') } }

我可以使用如下方式加载模块:

rush:js;"> var Vue = require('vue'); var TopHeader = require('components/header.js');

$符号

关于alias的详细使用介绍,请参见文档,本文并不是要介绍webpack文档,在这里介绍一下声明的vue$别名中的$符号:

这里的$符合是正则的文末匹配符,即只有当vue是最后一级路径时,webpack才会将该值解析成别名,进行别名与对应值替换,如vue/test.js中的vue是不会当作别名解析的,而components/header.js中的components则会按照声明的components别名进行解析,其结果是src/components/header.js。

resolve.extensions

该值定义解析模块时的查找文件的后缀顺序,如["",".js",".json"],会优先返回js文件,其次json文件,然后是其他文件,注意,这里数组传入了一个空字符串,他的作用是在未找到配置中所有列举的类型文件时,支持webpack返回其他类型文件,但是webpack2.x版本修改了,不支持传入空字符。

webpack插件配置

webpack还支持多种多样的插件拓展,你可以使用它们对你的项目webpack模块构建过程进行额外处理,如代码压缩,图片等资源提交压缩,构建异常捕获和提升,构建流程时间消耗比,等等,而关于这些插件使用的配置在plugins属性数组内,将在后续进行介绍。

项目本地调试与开发

为了方便开发和调试,通常都需要在本地主机开启服务,提供局域网内多终端访问,并且在文件变更时,实时刷新页面,正如grunt和gulp中browsersync插件提供的功能一样,webpack可以使用webpack-dev-server模块实现。

webpack-dev-server是一个Node.js的express服务器,以webpack开发中间件的形式为webpack包提供服务,当监听到源码文件变更时,会自动重新打包,并且支持配置自动刷新浏览器,重新加载资源。

安装

由于该插件只用于开发模式,所以通过以下npm指令安装:

rush:bash;"> npm install webpack-dev-server --save-dev

配置

启用webpack-dev-server时,其认开启8080端口,访问localhost:8080返回当前目录下的index.html,即执行指令当前目录下的静态资源,当然可以通过指令传递参数或在配置文件进行配置指定静态资源目录。

另外需要注意的是,开启webpack-dev-server后,变更文件重新打包后,并不会实际输出到配置的output目录,而是在publicPath属性声明的相对路径所在的内存中读取。

静态资源目录配置(CONTENT BASE)

rush:js;"> webpack-dev-server --content-base src/

执行以上指令开启服务后,webpack-dev-server将认在src/目录返回静态资源,当然也可以在webpack.config.js配置文件中指定:

rush:js;"> devServer: { contentBase: './src' }

访问http://localhost:8080和http://localhost:8080/index.html效果一样,均返回src目录下的index.html文件

PUBLICPATH与输出文件访问

在前文webpack配置一节中提到output.publicPath属性值表示,在浏览器访问webpack output输出文件时的基础相对路径,如设置:

rush:js;"> output: { path: 'dist/scripts',filename: 'app.js',publicPath: 'assets/' }

则在html文件中引用该app.js文件的方式如下:

rush:js;">

原文地址:https://www.jb51.cc/js/34655.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐