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}//代替preLoaders- loader种类分为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/'eq- import 'components/path/index'
 当设置- mainFiles: ["main"]时,- import 'components/path/'eq- import 'components/path/main'- webpack之plugins- webpack插件为webpack提供了更加强大的功能。插件分为内置和外置两种类型。之后的文章,我将详细讲解,插件使用,原理和自己编写插件。这里就不在描述了。