webpack作为包管理器,已经推出很多年了。在学习webpack之前,其实需要搞明白为什么要使用它,毕竟打包工具也有很多,比如:gulp,grunt,browserify,fis。
为什么使用webpack?
换句话说,webpack的特色是什么,有什么值得我们使用的:
- 根据文件(模块)之间的依赖关系,拆分成块,并按需进行异步加载。
- 强大的Loaders功能,将一切资源转化合适的格式,以共环境使用。
- 将一切资源视为块,进行打包转换,比如:传统的js模块(amd,cmd等),图片,less等。
- 丰富并具有扩展性的插件功能。
webpack和gulp的优势在哪?gulp主要是对文件的编译,压缩等功能,简化前端开发流程。webpack侧重在梳理模块之间的关系,将文件进行拆分,然后重新组合生成新的单个或多个文件,并利用加载器和插件进行
编译,压缩功能。
webpack之Entry
最简单配置,单入口:
|
|
上面的等同于:
这里的index.js文件就是入口文件,导入到名称为main的chunk里面。如果需要将多个依赖导入到一个chunk里面,可以给entry中直接传入数组或者对象的值为数组。
分离公共库
将公共库从应用程序中分离出来。
使用CommonsChunkPlugin插件,将main依赖vendors部分提取到vendors的bundle中,通过__webpack_require__()
调用。
提示:对象的key可以为目录形式。
webpack之Output
输出配置:
path
文件输出路径,资源存储路径。
publicPath
处理静态资源引用地址,比如:css,html等。
输出:
filename
文件输出名称
name:chunk的Name。
id:chunk的Id。
hash:compilation生命周期的hash替换。
chunkhash”被chunk的hash替换。
chunkFilename
非入口的chunk文件名称(非entry配置中文件)
sourceMapFilename
sourceMap文件的名称。
参数: [id]
,[file]
,[hash]
默认: [file].map
jsonpFunction
异步加载的chunk的JSONP函数。
默认:webpackJsonp
了解更多官网output
webpack之Module
noParse
确认模块中没有其他依赖的情况下,设置noParse
,webpack不会解析对应文件生成AST,并不会去寻找文件中的依赖。
缩短了打包时间。
参数:/jquery/
或[/jquery/]
rules
定义解析规则,按照规则,模块将有各自的创建方式。
事例:
|
|
每个rule分为三部分:条件,结果,嵌套规则。听到这里大脑里晕乎乎的,下面将解释这些内容。
rule条件
当满足所有匹配条件的文件,才会被rule解析。条件的入参有2种类型:
- 请求的资源的绝对路径,名称:resource
发起请求的资源绝对路径 , 名称:issuer
举个栗子:
a.js 文件中import “./a.css”。
那么,a.js的绝对路径就是issuer;
a.css的绝对路径就是resource;其中,test,include,exclude和resource对resource匹配,属性issuer对issuer匹配。
rule结果
条件满足后,rule结果才会执行。
还是有点晕,对吧。好比,if语句外面的是条件,括号里面的是执行内容,这里的rule结果就像是执行内容。
rule结果也有2种类型:
- 加载器loader:将resource类型资源文件进行转换。(使用过webpack的都比较熟悉loader)
- 解析器parser:解析器配置选项。(后面会详细解释)
rule嵌套
需要满足条件才能起作用。
通过rule.oneOf和rules配置。
官网代码:
rule部分参数
- test:判断条件,resource类型。
- exclude:排除resource类型文件目录。
- include:包含的resource类型文件目录。
- loader:
Rule.use:[{loader}]
的简写。如:loader:'style-loader!css-loader'
,不建议使用。 - options:
Rule.use:[{options}]
的简写。如:options:{key:vlaue}
。 use:包含loader属性,可选属性options。loader属性中配置需要使用的加载器,options为加载器参数。例子:
12345678910{ test:/.less$/,use:['style-loader',[loader:'css-loader',option:{'importLoaders':1}],'less-loader']}resourceQuery:资源匹配参数。如:
foo.css?inline
。enforce:用于替代webpack中 preLoaders和postLoaders。设置loader的种类。值为:’pre’或’post’。例子:
123456{test: /\.(js|jsx)$/,loader: 'eslint-loader',enforce:pre}//代替preLoadersloader种类分为4种:后置, 行内, 普通, 前置。执行顺序如名称,一目了然。行内是在require或import中使用的loader,例子:
123require("!my-loader!./my-module") 禁止preloaders生效。require("!!my-loader!./my-module") 禁止在配置文件中的所有加载器生效。require("-!my-loader!./my-module") 禁止loader和preloader,不禁止postloader。parser:解析选项对象。对解析器插件进行设置。大部分设置为布尔类型的值,少部分可以是其他。官网例子:
12345678910111213parser: {amd: false, // 禁用 AMDcommonjs: false, // 禁用 CommonJSsystem: false, // 禁用 SystemJSharmony: false, // 禁用 ES2015 Harmony import/exportrequireInclude: false, // 禁用 require.includerequireEnsure: false, // 禁用 require.ensurerequireContext: false, // 禁用 require.contextbrowserify: false, // 禁用特殊处理的 browserify bundlerequireJs: false, // 禁用 requirejs.*node: false, // 禁用 __dirname, __filename, module, require.extensions, require.main 等。node: {...} // 在模块级别(module level)上重新配置 node 层(layer)}光是例子,大家似乎还是不太明白。实际操作:入口文件app.js中输入
console.log(__dirname)
,然后执行打包,编译生成文件中生成了一个理解
执行函数function(module, __dirname)
,第二个参数为__dirname
。当在配置文件中设置parser:{node:false}
之后,编译后生成文件
中,没有这个执行函数。说到这里,大家都懂了吧。webpack之Resolve
设置模块的解析方式。
属性
alias:设置模块别名
12{newName : path/xxx/xxx } //newName是别名 require('newName') eq require('path/fileName'){newName$ : path/xxx/xxx } //精准匹配 不能 require('newName/path/file');modules:解析的模块名称,解析根据配置,具有先后顺序。
{modules:[path.join(__dirname,"./src"),'node_modules']}
- extensions:扩展名称设置,设置后自动解析,无需在添加
{extensions:['.js','.jsx']}
- enforceExtension:强制禁止或允许省略扩展名,布尔类型
descriptionFiles:设置解析时,对应引用模块(import React from ‘react’)的描述文件,模块将根据描述文件导入。默认:
descriptionFiles:['package.json']
例如:1234入口文件中:import React from 'react'; //文件中只有这行引用,因为修改描述文件将影响所有模块配置:`descriptionFiles:['package1.json']`//运行将会报错: Can't resolve 'react' in '/User.....'修改 react 模块中的package.json为package1.json ,再次运行,执行成功。所以,一般这个属性不会修改。mainFields:设置使用引入模块的package.json文件中哪个属性,来进行导入模块。例如:
1234配置:`mainFields:['newmain']` //执行入口文件。报错:Can't resolve 'react' in '/User.....'修改react的package.json中新增 newmain:"react.js"再次运行,执行成功。mainFiles:解析目录时默认的文件名。默认:
mainFiles: ["index"]
。例如:import 'components/path/'
eqimport 'components/path/index'
当设置mainFiles: ["main"]
时,import 'components/path/'
eqimport 'components/path/main'
webpack之plugins
webpack插件为webpack提供了更加强大的功能。插件分为内置和外置两种类型。之后的文章,我将详细讲解,插件使用,原理和自己编写插件。这里就不在描述了。