张登友,张登友的博客,张登友的网站——
初始化项目
mkdir webpack && cd webpack # 创建并切换目录
npm init -y # 初始化目录
初始化完成之后,打开刚才自动生成的package.json,添加如下内容:
"scripts": {
"start": "webpack"
}
并安装如下依赖:
npm i webpack webpack-cli webpack-dev-server --save-dev
在index.js文件添加内容
console.log('hello');
之后运行
npm run start
此时便会自动生成dist目录,里面会有一个main.js文件
webpack配置文件
前面提到,我们可以更改webpack的配置的。为了配置webpack,我们需要在根目录创建一个webpack.config.js文件。这是一个js文件,所以我们可以在里面写任意可运行的js代码。 首先更改入口文件和出口文件:
// webpack.config.js
const path = require("path");
module.exports = {
mode: "development", // "production" | "development"
// 选择 development 为开发模式, production 为生产模式
// 将入口文件指定为src目录下的index.js
entry: {index: path.resolve(__dirname, "src", "index.js")}, //指定入口文件
// 将输出文件目录改为build/
output: {
path: path.join(__dirname, "build"), //指定输出路径
filename: 'main.js' //指定输出文件名
}
};
添加html页面
html-webpack-plugin的作用就是改变webpack的工作方式,使webpack可以将打包后的js文件,添加到html页面中。首先,安装插件:
npm i html-webpack-plugin --save-dev
接着更改webpack.config.js,添加配置
const HtmlWebpackPlugin = require("html-webpack-plugin"); //引入HTML处理模块
module.exports = {//添加plugins字段部分
plugins: [
new HtmlWebpackPlugin({
template: path.resolve(__dirname, "src", "index.html")
})
]
}
此时webpack.config.js的完整配置文件如下
// webpack.config.js
const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
module.exports = {
mode: "development", // "production" | "development"
// 选择 development 为开发模式, production 为生产模式
// 将入口文件指定为src目录下的main.js
entry: {index: path.resolve(__dirname, "src", "index.js")},
// 将输出文件目录改为build/
output: {
path: path.join(__dirname, "build"),
filename: 'main.js'
},
plugins: [
new HtmlWebpackPlugin({
template: path.resolve(__dirname, "src", "index.html")
})
]
};
在原来的src目录下新建一个html文件,此处我并未引入script文件
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<meta name="Keywords" content="定义关键词" />
<meta name="Description" content="定义页面描述" />
</head>
<body>
<p>hello world</p>
</body>
</html>
此时再次运行
npm run start
build目录下会自动生成index.html文件,这是经过压缩的HTML文件,并且自动引入了main.js文件
所以,我们可以总结html-webpack-plugin的功能:
- 加载html文件。
- 将webpack打包后的js文件,通过script标签添加到html文件中。
webpack本地服务
作为开发者,肯定会用到本地服务,webpack提供了development server,可以很方便的启动一个本地服务,方便开发者进行开发工作。 首先我们需要安装webpack-dev-server包。
首先安装本地服务插件
npm i webpack-dev-server --save-dev
接着修改package.json文件的script部分
"scripts": {
"start": "webpack",
"dev": "webpack serve --mode development", // 开发模式
"pdc": "webpack serve --mode production" // 生产模式
},
并在webpack.config.js部分新增如下字段
devServer:{
port: 8000, //定义启动端口
static: path.join(__dirname,'build') //定义启动文件路径
}
这时候我们再运行
# 启动命令
npm run dev
# 停止命令服务按Ctrl+C
浏览器访问localhost:8000
即可看到我们打包后的页面了
加载css
需要用到webpack loaders(处理各种各样的模块和文件)。加载css文件,需要安装至少如下两个loaders:
- css-loader: 让我们可以使用import语句导入css文件。
- style-loader: 将css样式插入到html dom中。
安装命令
npm i css-loader style-loader --save-dev
接着在webpack.config.js添加如下字段
module: {
rules: [{
test: /\.css$/, //正则匹配以.css结尾的文件
use: ["style-loader", "css-loader"] //使用模块(刚刚安装的两个)
}]
}
注:loaders的顺序很重要,webpack加载loaders的顺序是从右到左
因为style-loader负责将样式插入到html中,程序总是先执行js代码,所以首先执行的是css的import,所以顺序错误了。
然后在入口文件index.js文件中添加如下字段
import "./style.css";
此时我们再访问localhost:8000,发现字体颜色也已经改变
我们可以再使用命令再生成一次文件
npm run start
此时html文件并未有style.css文件引入,但是通过浏览器访问后看见,字体也是红色的,css样式也已经成功加载,这是因为webpack将css一并打包进main.js文件了,我们可以通过打包后的main.js源码看见
加载sass
# 安装命令
npm install sass-loader sass webpack --save-dev
新建一个sass文件并添加样式
p
font-size: 30px
在index.js添加
import "./style.sass";
在webpack.config.js添加
{
test: /\.s[ac]ss$/i, //正则匹配sass和scss
use: [
// 将 JS 字符串生成为 style 节点
'style-loader',
// 将 CSS 转化成 CommonJS 模块
'css-loader',
// 将 Sass 编译成 CSS
'sass-loader',
],
}
最后使用npm run start生成文件并用浏览器访问localhost:8000,此时sass文件的样式已成功加载
加载babel-loader
使用babel-loader,首先安装
npm install -D babel-loader @babel/core @babel/preset-env
需要按照es6标准编译,那么你就安装一个 babel-preset-es2015, 同样,如果你要按照es7来编译,那么你就安装babel-preset-es2016:
npm install babel-preset-es2016 --save-dev
一般来说,如果想用最新的规范做编译,直接安装babel-preset-env就可以了,它包含了 babel-preset-es2015, babel-preset-es2016, and babel-preset-es2017,等价于babel-preset-latest,可以编译所有最新规范中的代码:
npm install babel-preset-env --save-dev
然后在webpack.config.js的model部分添加如下字段
{
test: /\.m?js$/,
exclude: /(node_modules|bower_components)/,
use: {
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env', //也可以写成presets:['env']
// {
// targets: {
// browser: ['> 1%'] //babel做编译的时候,编译出来的语法支持所有市场占有率超过1%的浏览器,把参数变成chrome,那么打包出的代码,只能保证在chrome上运行正常,其他浏览器能不能跑就不好说了,因为你配置的打包程度就是兼容chrome即可。
// }
// }
]
}
}
}
另一种做法是在项目的根目录下新建一个.babelrc
文件,内容如下:
{
"presets": ["@babel/preset-env"]
}
新建测试文件es6.js
// es6.js
const fn2 = (a, b) => {
return a + b;
};
console.log(fn2(1, 2));
然后运行命令生成文件即可
npm run start
完整配置文件
文件夹结构如下
.
├── build
│ ├── index.html
│ └── main.js
├── node_modules
├── package-lock.json
├── package.json
├── src
│ ├── es6.js
│ ├── index.html
│ ├── index.js
│ ├── style.css
│ └── style.sass
└── webpack.config.js
// webpack.config.js
const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
module.exports = {
mode: "development", // "production" | "development"
// 选择 development 为开发模式, production 为生产模式
// 将入口文件指定为src目录下的main.js
entry: {
index: path.resolve(__dirname, "src", "index.js")
},
// 将输出文件目录改为build/
output: {
path: path.join(__dirname, "build"),
filename: 'main.js'
},
plugins: [
new HtmlWebpackPlugin({
template: path.resolve(__dirname, "src", "index.html")
})
],
devServer: {
port: 8000,
static: path.join(__dirname, 'build')
},
module: {
rules: [{
test: /\.css$/,
use: ["style-loader", "css-loader"]
},
{
test: /\.s[ac]ss$/i,
use: [
// 将 JS 字符串生成为 style 节点
'style-loader',
// 将 CSS 转化成 CommonJS 模块
'css-loader',
// 将 Sass 编译成 CSS
'sass-loader',
],
},
{
test: /\.m?js$/,
exclude: /(node_modules|bower_components)/,
use: {
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env', //也可以写成presets:['env']
// {
// targets: {
// browser: ['> 1%'] //babel做编译的时候,编译出来的语法支持所有市场占有率超过1%的浏览器,把参数变成chrome,那么打包出的代码,只能保证在chrome上运行正常,其他浏览器能不能跑就不好说了,因为你配置的打包程度就是兼容chrome即可。
// }
// }
]
}
}
}
]
}
};
// package.json
{
"name": "webpack",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"start": "webpack",
"dev": "webpack serve --mode development",
"pdc": "webpack serve --mode production"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"webpack-cli": "^4.9.1"
},
"devDependencies": {
"@babel/core": "^7.16.10",
"@babel/preset-env": "^7.16.10",
"babel-loader": "^8.2.3",
"css-loader": "^6.5.1",
"html-webpack-plugin": "^5.5.0",
"sass": "^1.49.0",
"sass-loader": "^12.4.0",
"style-loader": "^3.3.1",
"webpack": "^5.66.0",
"webpack-dev-server": "^4.7.3"
}
}
一键安装命令(仅适用于上面用到的插件,HTML,js,css,sass/scss)
npm i webpack webpack-cli webpack-dev-server html-webpack-plugin webpack-dev-server css-loader style-loader sass-loader sass babel-loader @babel/core @babel/preset-env --save-dev
一些概念
入口文件(entry point)
webpack工作开始的地方,就是一个js文件。webpack通过这个文件内的import,收集其他模块文件,在通过其他模块文件内的import语句,收集其他依赖,最后将所有模块文件打包到一起,形成一个整体可运行的代码。 默认的入口文件是 src/index.js
。
输出文件(output)
output就是webpack通过build过程打包后形成的文件。默认的输出文件夹为根目录下的dist/
文件夹。
加载器(loaders)
loaders是一些第三方扩展包,可以帮助webpack处理加载各种类型的文件。例如有处理css、image文件的loaders。如果没有loaders,webpack本身是不支持css文件的。
插件(plugins)
plugins也是第三方插件,它可以改变webpack的工作方式,例如有些插件可以设置webpack的环境变量。
模式(mode)
webpack有两种工作方式:development(开发模式)和production(生产模式)。 主要的区别就是production模式下,产生的捆绑包(文件)更小,去掉了在运行下无关的注释,空格等等。这样可以加快用户加载代码的速度。
参考以下文档