这是我参与「第五届青训营 」伴学笔记创作活动的第 13 天
Webpack
01 入门应用
理解打包流程
熟练掌握常用配置项、Loader、插件的使用方法,能够灵活搭建集成 Vue、React、Babel、Eslint、Less、Sass、图片处理等工具的 Webpack 环境
掌握常见脚手架工具的用法,例如:Vue—cli、create—react—app、@angular/cli
02 进阶
理解 Loader、Plugin 机制,能够自行开发 Webpack 组件
理解常见性能优化手段,并能用于解决实际问题
理解前端工程化概念与生态现状
03 大师级
阅读源码,理解 Webpack 编译、打包原理,甚至能够参与共建
简介
用vue项目来举例: 浏览器它是只认识js,不认识vue的。而我们写的代码后缀大多是.vue的,在每个.vue文件中都可能html、js、css甚至是图片资源;并且由于组件化,这些.vue文件之间还有错综复杂的关系。所以项目要被浏览器识别,我们就要使用webpack将它们打包成js文件以及相应的资源文件。
或者这么理解,我们以vue项目的形式编写项目逻辑,浏览器以他理解的方式来运行项目。webpack把我们的vue项目想表达的所有意图传递给浏览器让浏览器去运行。
Webpack的运行需要依赖Node.js
使用:安装——配置——执行
使用
入口处理——从entry开始启动编译流程
依赖解析——从entry开始,根据import等找到依赖
资源解析——根据module配置,将png、css等非标准JS资源转译为JS内容
资源合并——将转义后的资源文件合并打包为可直接在浏览器中运行的JS文件
vue-cli 配置 package.json
vue-cli自带webpack。
在package.json中,不仅可以记录安装的内容,还可编写脚本。注意看package.json中的“scripts”配置项。
// 这是package.json
{
"name": "zhihu_demo",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"build": "webpack --config webpack.config.js"
},
"repository": {
"type": "git",
"url": "git+https://github.com/rehellinen/zhihu_demo.git"
},
"author": "",
"license": "ISC"
}
配置 webpack.config.js
webpack.config.js文件是webpack的默认配置文件。之前我们使用命令行$ webpack entry.js output.js来实现打包,其实webpack可以有更多的打包配置,这些配置都是在webpack.config.js中完成的。下面是一个简单的webpack.config.js。
const webpack = require("webpack")
module.exports = {
entry: {
entry: "./app/entry.js",
},
output:
{
path: __dirname + "/dist",
filename: 'bundle.js',
},
devtool: false,
devServer:{
hot:true,
open:true
},
module: {
loaders: [
{
test: /.js$/,
loader: 'babel',
exclude: /node_modules/
},
{
test: /.sass$/,//处理sass后缀的文件
exclude: /node_modules/,
use: [
'style-loader',
'css-loader',
'sass-loader'//用了这三个来处理
]
}
]
},
plugins: [
// 该插件用于把新生成js自动部署到html中
new HtmlWebpackPlugin({
// 指明该插件需要处理的html模版
template: path.resolve(__dirname, './index.html')
})
// 该插件清除上次残留的文件
new CleanWebpackPlugin()
]
}
entry
entry是配置webpack的入口文件,上面的代码中我们将app目录下的entry.js作为入口文件。webpack会将与entry.js有关的资源都进行打包。
一般一个html页面对应一个入口。webpack将从入口js文件开始一步步分析该页面,只要是页面用到的文件(包括图片和样式文件等等),都会被转成对应的js文件。
output
Webpack将打包后的文件将输出到哪里。
loaders
loader是webpack的加载器,可以帮我们处理各种非js文件,转换为js。如css样式,vue、jsx、weex等后缀的代码,JPG、PNG图片等。所以我们一般会在package.json中看到各种***-loader。这些就是各类资源的loader加载器。
在module的loaders数组中可以有多个对象,每个对象就是一个加载器。最重要的就是text属性和use属性
一些loader
| js | css | html | assets |
|---|---|---|---|
| babel-loader | css-loader | html-loader | file-loader |
| eslint-loader | style-loader | pug-loader | val-loader |
| ts-loader | less-loader | posthtml-loader | url-loader |
| buble-loader | sass-loader | json5-loader | |
| vue-loader | stylus-loader | ||
| postcss-loader |
babel——转译ES6代码。webpack打包的文件默认是不支持ES6的,我们需要用babel转译。在webpack.config.js中添加babel-loader的配置
sass-loader——处理 Scss 文件。在配置 Scss 文件的处理规则时,设置 rule 对象的 use 属性为 ['style-loader', 'css-loader', 'sass-loader'] 即可。
- sass-loader:sass转为css
- css-loader:css包装成module.exports = "${css}"的符合js的格式
- style-loader:把css包入require语句,并用injectstyle等注入到页面的style标签
思考:与在html中使用css相比,使用loader有何优劣?
plugins
很多知名工具都设计了所谓”插件“架构。因为功能很多很复杂,了解这个流程细节的上手成本高。所以插件——对扩展开放,对修改封闭
插件可以扩展webpack的功能,让webpack不仅仅是完成打包,甚至各种更复杂的功能,或者是对打包功能进行优化、压缩,提高效率。
插件用起来还是简单,但是问题是要搞懂插件内部的配置
插件举例
html-webpack-plugin
平时打包过程中,除了HTML文件外的其它文件都被打包了,当在线上部署时,我们还得自己复制HTML到dist,然后手动添加生成的js到HTML中,这非常不友好。
可以用它生成一个index.html,其中已经自动添加了当前目录下的build.js
HotModuleReplacementPlugin
模块热更新插件。Hot-Module-Replacement 的热更新是依赖于 webpack-dev-server,后者是在打包文件改变时更新打包文件或者 reload 刷新整个页面,HRM 是只更新修改的部分。
HotModuleReplacementPlugin是webpack模块自带的,所以引入webpack后,在plugins配置项中直接使用即可。
DashboardPlugin
devtool
在webpack中新增一行 devtool: eval-source-map , 将会生成source-map 供浏览器展示,信息写到源文件bundle.js里
将配置修改为devtool: source-map,重新打包后,则会生成独立的source-map文件
devServer
hot设置为true就自动更新
watch
持续看代码
mode
用development的话,会全部导入编译
用production,且optimization的usedExperts为true,一些不被使用的变量等就不被引入了,相当于tree-shaking。没用的代码就不打包,产物就会变得很小了
optimization
打包之后
打包完成就会出现一个在 dist 目录下有一个 bundle.js 文件。
有了打包文件,我们还需要创建一个 index.html 。创建一个id为app的div元素用于显示Vue组件内容,然后将打包好的bundle.js引用进去。
现在,到项目目录中找到 index.html 页面,我们就可以像打开静态网页一样打开我们完成的项目。
又可能出现引用资源的路径问题,我们需要修改一下项目目录下的config文件夹里的index.js中的assetsPublicPath