目标:让你的webpack具备以下能力
- 具备将编译后的js自动插入html中的能力
- 具备编译less、css样式并将样式插入Dom的能力
- 具备处理静态资源的能力
- 具备ES6编译成ES5的能力,让你的代码兼容低版本浏览器
以上目标是实现搭建脚手架的基础
webpack实现简单编译打包
1、创建文件夹,以项目名称命名;
2、进入该文件夹,执行npm init,快速初始化package.json文件
3、项目内安装webpack和webpack-cli;
yarn add webpack webapck-cli -D
4、package.json的scripts属性内添加命令
{
...,
"scripts": {
"start": "webpack"
}
}
5、webpack默认入口文件是./src/index.js。所以我们可以先尝试在根目录新建src文件夹,src文件夹内新建index.js文件。
// index.js
let a = 1;
let b = 2;
let c = a + b;
这个时候你会发现为什么执行命令 npm run start后,webpack编译后的dist/main.js文件为空?
因为不指定模式,webpack的mode会默认是生产环境production,就会开启treeshaking摇树,帮我们去除死代码,当然还会默认开启别的一些列优化
// index.js
for(let i = 0; i < 10; i++){
console.log(i);
}
如果是上述表达式,treeShaking就不会以为是死代码,具体的死代码规则可以深入了解下webapck的tree shaking
给webpack编译指定开发模式可以关闭摇树(tree shaking)
{
...config,
"scripts": {
"start": "webpack --mode development"
},
}
到目前为止,webapck简单的编译打包已经实现了,只不过只能编译js、json格式的文件,如果想要支持css、html、svg、es6等资源还需要配置一些loader;
初始webpack的左膀右臂(常见loader、plugin)
1、html-webpack-plugin插件
除非我们搭建的是组件库,否则我们肯定会用到html,webpack不认识html,就只能借助插件去解析 在项目根目录配置webpack.config.js 在根目录创建index.html
// webpack.config.js
const HtmlWebpackPlugin = require('html-webpack-plugin');
const path = require('path');
module.exports = {
module: {
rules: [
]
},
plugins: [
new HtmlWebpackPlugin({
filename: 'index.html', // 打包后的文件名
template: path.resolve(__dirname, './index.html') // html模板
})
]
}
现在我们进行一次打包,会发现打包后的html,会包含引入js文件的代码,到目前为止,简单的单页面应用已经配置完成
总结html-webpack-plugin的作用:
-
帮我们将 webpack 打包生成的文件(比如 js 文件、css 文件)嵌入到 html 文件中,我们打包的js、css有可能存在hash值,这样能避免我们每次手动去更新hash值;
-
支持根据不同的入口生成不同的html模板,配置多页面应用
2、style-loader、css-loader、less-loader
yarn add style-loader css-loader less less-loader -D
- style-loader: 将样式通过style标签插入Dom,通过生成一些js代码(创建style标签将样式插入html)
- css-loader:解析css文件中的@import和url语句,处理css-modules,并将结果作为一个js模块返回
- less-loader:将less编译为css
module.exports = {
...,
module: {
rules: [
{
test: /(\.css|\.less)$/,
use: [
'style-loader',
'css-loader',
'less-loader'
]
}
]
},
}
链式调用关系 less-loader -> css-loader -> style-loader
总结:loader的解析顺序是从右到左,从三个loader的作用可以得知,他们必须有先后顺序执行,否则会带来一些问题
3、file-loader、url-loader (webpack5已废弃)
-
file-loader
- API:v4.webpack.js.org/loaders/fil…
- 作用:file-loader 就是在 import/require 一个文件时,会将该文件生成到输出目录,并返回该文件的地址;
-
url-loader
- API:v4.webpack.js.org/loaders/url…
- 作用:将文件作为 data URI 内联到 bundle 中;相当于把文件翻译成了一串字符串,再把这个字符串打包到 JavaScript
// 实际开发中,如果是webpack5,不需要进行下列配置
module:{
rule: [
{
test: /\.(png|jpg|gif)$/,
use: [
{
loader: 'url-loader',
options: {
// 大于 1000 bytes 的文件都走 fallback,fallback默认是走的file-loader
limit: 1000,
},
},
],
type: 'javascript/auto' // 如果是webpack5,需要指定该type才可以使用url-loader,否则会走webpack默认内置的asset
}
]
}
关于webpack5的资源模块介绍请移步webpack.docschina.org/guides/asse…
4、babel
babel,之前叫6to5,babel是一种转译器,将ES6+的代码转换成ES5代码,更好的兼容各种浏览器,但是babel只对ES6+的语法进行转换,针对一些新的API是不做转换的,因此还需要在babel-loader上配置@babel/polyfill
@babel/preset-env: 基于你的实际浏览器及运行环境,自动的确定babel插件及polyfills
// 安装
npm i babel-loader @babel/core @babel/preset-env -D
//配置babel-loader方式1
// 在webpack.config.js中使用
module: {
rules: [
{
test: /\.js$/,
loader: 'babel-loader',
}
]
}
// 在根目录新建.babelrc文件
{
"presets": ["@babel/prset-env"]
}
//配置babel-loader方式2
// 在webpack.config.js中使用
module: {
rules: [
{
test: /\.js$/,
use: {
loader: 'babel-loader',
options:{
// 和.babelrc的书写规范一致
presets: ['@babel/preset-env']
}
}
}
]
}
另外,如果期望在项目中使用可选链、双问号,需要在babel中配置相关插件