似水的流年 为何不去邂逅一场繁华的悸动
Grunt/Gulp流程
构建&执行过程
要完全理解webpack整个构建过程是有难度的,这需要你去学习webpack的源码,这里简单地说一下webpack的执行过程:
- webpack先识别我们写的配置表选项,进行一系列的初始化
- webpack从入口文件开始进行编译,递归解析对应依赖的文件,需要进行预处理的文件会根据配置的loader去转换
- 根据不同块之间的依赖进行分组,分成不同的
chunk
- 将不同的
chunk
转成对应的输出文件 - plugin会贯穿这个编译的过程,会在适当的时机调用适当的插件
webpack工作流程
把你的项目当做一个整体,通过一个给定的主文件(如:index.js),Webpack将从这个文件开始找到你的项目的所有依赖文件(Dependency Graph,从入口文件开始进行编译,递归解析对应依赖的文件),使用loaders处理它们,最后打包为一个浏览器可识别的JavaScript文件。
package.json配置
自定义命令
1 | "scripts": { |
总结一下写阮一峰的15个demo遇到的问题:
webpack加载器解析顺序
无论是字符串语法style-loader!css-loader
,亦或是数组语法['style-loader', 'css-loader']
,webpack解析规则都是从右至左,依次解析并执行加载器处理文件,前一加载器处理的输出就是下一加载器处理的输入,直到最后加载器处理完成;此处即webpack先调用css-loader加载器处理css文件,然后将处理结果传递给style-loader加载器,style-loader接受该输入继续处理。
(1)注意babel-loader的rule一定要在url-loader下面
1 | main.jsx |
解释:好吧,我才刚学,等我会了再更新。
(2)让webpack.config.js支持 es6写法
不喜欢commonJS的写法,还是习惯es6的import,但是直接import发现并不支持 import,报语法错误了。
以下为解决方法
1 | 第一、把webpack.config.js改名为webpack.config.babel.js(前提是目录下装了babel-loader 和 babel-core) |
1 | "devDependencies": { |
最后 npm install
或者 npm i
Nice!可以webpack -p了
重点来了,之所以不支持es6,是因为我写的demo是webpack 1.00版本了,上个世纪的版本,新的webpack版本好像已经支持es6,而且webpack2.0以上,不能这样实现在webpack.config.js中书写es6语法。
插件系统
UglifyJs Plugin
配置
1 | import UglifyJsPlugin from 'uglifyjs-webpack-plugin'; |
作用
压缩output(bundle.js)Js.code
HTML Webpack Plugin & Open Browser Webpack Plugin
配置
1 | import HtmlwebpackPlugin from 'html-webpack-plugin'; |
作用
HTML 为你创建一个index.html
OpenBrowser 当webpack加载的时候打开一个新标签页
代码拆分
webpack使用 require.ensure定义split point 。
1 | // main.js |
上面的代码告诉webpack ./a.js
应该从 bundle.js
被拆分开,并创建一个新的chunk file
1 | // a.js |
此时,你不用在index.html中手动引入chunk.js,也不用在webpack.config.js的output里配置chunk。
1 | index.html |
bundle-loader
代码拆分的另一种方式。
1 | var load = require('bundle-loader!./a.js'); |
Q 利用bundle-loader实现按需加载
源码阅读,代码简短,也是通过require.ensure()实现。
CommonsChunkPlugin
有利于浏览器缓存和节省带宽
配置
1 | var webpack = require('webpack'); |
用CommonsChunkPlugin拆分第三方库
1 | main.js |
注意 entry.vendor: [‘jquery’]告诉webpack jquery要被包含在commmon chunk (vendor.js中),所以CommonsChunkPlugin中的name属性和entry中的vendor键必须相同,也可以是其它名字。
从上面也可以发现每个模块中要使用jquery都要require(‘jquery’)。
如果希望$作为全局变量,而不使用require(‘jquery’),如下:
1 | // main.js |
使用ProvidePlugin可以自动载入模块,而不需要import或者require()模块。
暴露全局变量 externals
当我们需要使用一些全局变量,又不希望变量包含在bundle文件中,不需要webpack处理,编译进文件中,在我们需要,使用它的时候可以通过CMD、AMD、或者window全局方式访问。
假设我们自己有个工具库,tools.js,它并没有提供给我们UMD的那些功能,只是使用window或者global的方式把工具的对象tools暴露出来
1 | utils.js |
引入
1 | <script src="http://xxx/tools.min.js"></script> |
可能我们会直接引用
1 | const res = tools.add(1,2) |
既然我们是模块化开发,当然要杜绝一切全局变量了,我们要用require的方式。
1 | `const tools = require(``'mathTools'``)``const res = tools.add(1,2)` |
这时我们再来配置一些externals即可
1 | module.exports = { |
打包后会有这一段
1 | module.exports = mathTools; |
要注意的点
externals: { mathTools: "tools" }
和const tools = require('mathTools')
tools和mathTools是对应的。并且utils.js
中的tools
变量要和const tools = require('mathTools')
的tools
变量对应。
皮毛的东西,继续填坑吧,哎。