常用loader
loader: webpack本身只能打包Javascript文件,对于其他资源例如 css,图片,或者其他的语法集比如jsx,是没有办法加载的。 这就需要对应的loader将资源转化,加载进来。
样式
- css-loader : 解析css文件中代码
- style-loader : 将css模块作为样式导出到DOM中
- less-loader : 加载和转义less文件
- sass-loader : 加载和转义sass/scss文件
- postcss-loader: 自动添加css的兼容前缀
脚本转换编译
- script-loader : 在全局上下文中执行一次javascript文件,不需要解析
- babel-loader : 加载ES6 代码后使用Babel转义为ES5后浏览器才能解析
Files文件
- url-loader : 多数用于加载图片资源,超过文件大小显示则返回data URL
- raw-loader : 加载文件原始内容(utf-8格式)
加载框架
- vue-loader : 加载和转义vue组件
- react-hot-loader : 动态刷新和转义react组件中修改的部分
校验测试:
eslint-loader等: 打包时通过 ESLint 检查 JavaScript 代码,当启用了eslint-loader之后,会影响打包速度。
vue-template-compiler
作用: 该模块可用于将 Vue 2.0 模板预编译为渲染函数(template => ast => render),以避免运行时编译开销和 CSP 限制。大都数场景下,与 vue-loader一起使用,只有在编写具有非常特定需求的构建工具时,才需要单独使用它,vue-template-compiler 的代码是从 vue 源码中抽离的!因此,vue 和 vue-template-compiler 的版本必须一致(同一份源码)!
vue-loader
用于 Vue 单文件组件的 webpack 加载器。*.vue 文件是一种自定义文件格式,使用类似于 HTML 的语法来描述 Vue 组件。每个 *.vue 文件都包含三种类型的顶级语言块:<template>,<script>
和 <style>
,以及其他可选的自定义块, vue-loader 将解析文件,提取每个语言块,如有必要,将它们通过其他加载器进行管道传输,最后将它们组装回ES 模块,其默认导出为 Vue.js 组件选项对象。
常用plugin
使用plugin丰富的自定义API,可以控制webpack编译流程的每个环节,实现对webpack的自定义功能扩展。
plugin是一个具有 apply方法的 js对象。apply方法会被 webpack的 compiler(编译器)对象调用,并且 compiler 对象可在整个 compilation(编译)生命周期内访问。
- define-plugin:webpack模块自带的, DefinePlugin 允许在 编译时
创建配置的全局常量,这在需要区分开发模式与生产模式进行不同的操作时,非常有用。
例如,如果想在开发构建中进行日志记录,而不在生产构建中进行,就可以定义一个全局常量去判断是否记录日志。 - copy-webpack-plugin:将个别文件或整个目录复制到构建目录。
- postcss-namespace: css命名
- BannerPlugin:对所有的文件打包后添加一个版权声明
- uglifyjs-webpack-plugin:对 JS 进行压缩混淆
- HtmlWebpackPlugin:可以根据模板自动生成 html 代码,并将打包生成的js,和css文件,插入到该html中
- Hot Module Replacement:在每次修改代码保存后,浏览器会自动刷新,实时预览修改后的效果
- extract-text-webpack-plugin:将 js 文件和 css 文件分别单独打包,不混在一个文件中
- optimize-css-assets-webpack-plugin 不同组件中重复的 css 可以快速去重
- html-withimg-loader 页面中经常会用到img标签,img引用的图片地址也需要一个loader来帮我们处理好
- clean-webpack-plugin:在我们每次npm run build的时候都会在dist目录下创建很多打好的包,如果积累过多可能也会混乱,所以应该在每次打包之前将dist目录下的文件都清空,然后再把打好包的文件放进去
let CleanWebpackPlugin = require('clean-webpack-plugin');
module.exports = {
plugins: [
// 打包前先清空
new CleanWebpackPlugin('dist')
]
}
babel
Babel会将ES6的代码转成ES5的代码
@babel/core
babel-loader
@babel/preset-env
需要先安装,在配置
module.exports = {
module: {
rules: [
{
test:/\.js$/,
use: {
loader: 'babel-loader',
// 配置选项里的presets
// 包含ES6还有之后的版本和那些仅仅是草案的内容
options: {
presets: ['@babel/preset-env']
}
}
include: /src/, // 只转化src目录下的js
exclude: /node_modules/ // 排除掉node_modules,优化打包速度
}
]
}
}
打包原理
(1)读取入口文件,如项目中的main.js;
(2)由入口文件,解析模块所依赖的文件或包,生成ATS树;
(3)对模块代码进行处理:根据@babel工具转换ATS树(es6转es5、polyfill等);
(4)递归所有模块
(5)生成浏览器可运行的代码
打包优化
1.自带优化
a)tree-shaking:依赖关系解析(不用的不打包),只在production环境下执行
b)scope-hosting:作用域提升,有结果输出的直接打包出结果,相应的变量不进行打包
2.插件或其他自定义配置
速度方面:
a)happypack 多线程打包,但是项目体积小的话反而更慢
体积方面:
a) webpack.IgnorePlugin,不需要的语言包不打包
b) external:{‘vue’:‘vue’}配置不需要打包的文件
c) modules:{noParse:/vue/} 配置不需要解析的文件
d) 动态链接库:一个想要提取出来的包,单独打包,然后放到CDN上
e) 抽离公共代码块: splitChunkPlugin