本文是混子前端之前在学习 webpack 时整理的说明文件 有些枯燥 但整理的很详细,其中代码模块我已图文备注说明,如果你刚开始准备学习 webpack 那本文对你帮助很大,一定要按照文字走完全流程
webpack基本介绍
webpack: 给js准备的一个打包工具,可以把很多模块打包成很少的静态文件,有一个自己的特性:代码分割 (code splitting),还有一个loaders的概念,模块是通过loaders处理各种文件,无论js是用 commonJS、AMD、ES6、CSS、Images、JSON、Coffeescript、LESS... 都可以用loaders 处理,甚至还可以是自己定义的一些文件,如:.vue、.JSX文件都可以通过 loaders 处理
- 会切分依赖树,会把依赖树切分不同代码块里,然后按需加载依赖,和前端懒加载概念相似
- 保持初始化加载时间更少
- 任何静态资源都可以视为一个模块在项目中引用,在开发中起到很多便利,整合第三方类库,把第三方类库视做模块在项目中引用
- 可以在整个打包过程中,每一步都可以自定义去做事情
- code Splitting 代码分割
- loaders
- 插件系统,模块热更新 plugin system:在开发过程中提高开发和调试效率
- 一切皆为模块
- 按需加载
webpack安装和命令行
观察hello.bundle.js:
可以看到world代码被打包进来了,编号是 1,写在 hello.js 中的 require 被替换成webpack_require,webpack用这种方式去寻找依赖,把文件打包到一起,这是简单工作方式
可以看出css-loader让webpack去处理css文件,style-loader通过css-loader处理完的文件,把处理完的文件新建一个style标签插入到html head里面
> 如果在代码里每次 require css 都需要写一长串的话 style-loader!css-loader! 的话会很麻烦,也可以用打包命令:
webpack hello.js hello.bundle.js --module-bind 'css=style-loader!css-loader'
用到了webpack中 --module-bind 的参数,相当于把这个模块绑定:如果是css文件就先交给css-loader,css-loader之前要style-loader
webpack hello.js hello.bundle.js --module-bind 'css=style-loader!css-loader' --watch
1、--progress : 看到打包的百分比;
2、 --display-modules:看到打包的模块和用到的loader列出来;
3、--display-reasons:打包 模块的原因列举出来
建立项目的webpack配置文件
建立 webpack.config.js 原因:如果直接使用 webpack 命令,会直接在项目根目录寻找webpack.config.js 作为默认配置去运行,这时不需要指定任何参数,会直接读取 config 里面的内容,也可以使用 --config 指定其他配置文件
webpack配置的entry和output
1、entry 打包2个平行的js文件可以写成数组模式
打包后的 bundle.js 文件
这个0模块把两个不相干的模块,require 打包到一起,这样就可以在开发中使用
2、在多页面应用程序,可以用到entry为对象的形式,对象的key是 chunk name,value 是entry,根据不同页面分配不同的 chunk,如果 entry 的 objcet 是多余一个的,那打包好的文件就不可以是一个了,这时候就要修改 output,在 output 中修改 filename 属性,这里如果指定了 hash,如下图:
打包后的多个文件 hash 值都一样,所以引出了 chunk-hash,如下图:
插件生成的 index.html 和项目根目录的 index.html 没有任何关系,这不满足需求。如果以根目录index.html去生成dist下index.html,就要在 webpack.config.js 中继续操作
这时就可以把根目录下 index.html 中 script src 标签删掉,打包后的 index.html 会自动引入压缩并带有 hash 值的 js 文件,这时候发现一个问题,所有压缩好的文件都在dist/js下,这和实际生产不符,实际需要 index.html 在 dist/js 目录外的,还要去修改 webpack.config.js,将不是 js 文件都创建到 dist 目录,将js文件 filename 指定相对路径
打包后文件结构如下图:
除了 template 还有一些其他参数:
如何做到在 webpack.config.js 中修改 index.html 文件 title
这时候可以对 htmlWebpackPlugin进行遍历,因为类似于模版文件引擎写法,可以直接编写:
继续探索,假如想把一部分 js 放到 index 的 head 标签里,一部分想放到 body 标签里,只通过配置是做不到的,所以要改变模版:
继续探索,假如打包后要上线,上线后的地址和本地的相对路径肯定不一样,这时候要借助output 新属性:[[ publicPath ]]
如果希望把页面性能达到极致,把一些初始化脚本直接嵌入到页面,而不是链接的形式引入到页面,现在全都是链接,即:script src=***,这样可以达到效果但会增加http请求,现在可以把初始的代码直接inline入到页面,可以大大提高运行速度,因为没有http请求:
通过 htmlWebpackPlugin.files.chunks.main.entry 截取掉占位符
webpack如何处理想要的资源文件
babel-loader 打包编译是很慢的,官网给出新的参数
exclude:loader 的排除范围(不明显)
include:loader的处理范围
exclude 比较慢的原因是没有用到绝对路径,在项目中怎么获取到绝对路径?
同理 include也是写绝对路径
首先要在命令行中:npm install style-loader css-loader --save-dev
在webpack.config.js中添加loaders
最后npm run webpack即可,接下来查看,如果有一个需要兼容性的样式怎么处理?假如说:display:flex要我们手动添加前缀进行兼容,现在有一个loader去处理
npm install postcss-loader --save-dev
postcss-loader是css的一个后处理器,安装好之后,需要继续安装 autoprefixer 这是给postcss的插件,是用来处理css前缀的
npm install autoprefixer --save-dev
如果在 css 中使用@import一个文件,会发现display:flex没有生成兼容性的前缀,也就是说他经过了css-loader和style-loader,没有经过postcss-loader,处理办法是借助precss插件,在项目中安装:npm install precss --save-dev
npm install less-loader --save-dev npm install less --save-dev
这里如果在 less 中使用 import 写法,可以不用写 require('precss'),因为 less-loader 已经帮我们做了处理,如果使用sass作为项目预处理器使用方法与less一样
1、用webpack把模版文件当作字符串处理
2、webpack把模版文件 当成已经编译好的模版处理函数;首先安装html-loader
npm install html-loader --save-dev
现在如果,模版文件不是以html结尾,而是以.tpl结尾的模版文件,那要如何处理 ?
首先要引入新的loader:
npm install ejs-loader --save-dev
然后在webpack.config.js中添加规则,让.tpl结尾的文件用 ejs-loader 处理
1、css中很多的background图片
2、模版结构里引用了img文件
3、根部index.html引用了img文件
解决办法:
1、尽可能在模版中使用绝对地址
2、可以在src中使用${ }的形式把图片引用进来,这时可以在控制台中看到图片地址被替换了
介绍一个新的loader,npm install url-loader --save-dev,当图片或者文件大小大于指定的limit 指定的大小,会丢给 file-loader 去处理,当小于limit设置值的时候会把图片或者文件转为base64 位编码
这时可以在命令窗口看到,原本18k的图片被压缩很小的图片被打包进项目
最后老规矩,欢迎点赞和纠错,祝大家工作愉快!