webpack
是一个模块打包工具。参考《深入浅出 Webpack》
Webpack 的本地搭建
1、新建文件夹 webpack-demo。
// index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app"></div>
<script src="./src/index.js"></script>
</body>
</html>
// src/index.js
import Header from './header.js';
import Content from './content.js';
new Header();
new Content();
// src/header.js
function Header() {
var dom = document.getElementById('app');
var header = document.createElement('div');
header.innerText = 'header';
dom.append(header);
}
export default Header;
// src/content.js
function Content() {
var dom = document.getElementById('app');
var content = document.createElement('div');
content.innerText = 'content';
dom.append(content);
}
export default Content;
2、npm init [-y]
初始化项目,生成 package.json 文件。
3、安装 webpack 和 webpack-cli。
上面代码中import
语句是使用ES6
语法,浏览器不能识别,需要通过webpack
转换后才能正常运行。
# 在项目里安装,因为可能不同项目中使用不同 webpack 版本。
$ npm i webpack webpack-cli -D
$ webpack -v // 打印出全局的版本
$ npx webpack -v // 打印出当前目录的版本
$ npm info webpack // 安装前查看版本号
$ npm install webpack@4.16.5 webpack-cli -D // 安装指定版本
4、修改 package.json 文件。
加上"private": true
表示私有,设置为true
时,npm
拒绝发布。
"main": "index.js"
可以去掉。
"dev": "webpack"
修改打包命令,之前是npx webpack
打包,现在是npm run dev
打包。
5、项目根目录下新建webpack的配置文件webpack.config.js
。
// webpack.config.js
const path = require('path');
module.exports = {
mode: 'production',// 默认值为 production
// JavaScript 执行入口文件
entry: './src/index.js',
output: {
// 将所有依赖的模块合并输出到一个 bundle.js 文件
filename: 'bundle.js',
// 将输出文件都放到 dist 目录下
path: path.resolve(__dirname, './dist'),
}
};
# 设置 webpackconfig.js 为配置文件
$ npx webpack --config webpackconfig.js
6、npx webpack/npm run dev
打包,生成dist
文件夹,里面有bundle.js
文件。
7、在index.html
将打包文件引入,再打开index.html
,页面运行成功。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app"></div>
<!-- 导入 Webpack 输出的 JavaScript 文件 -->
<script src="./dist/bundle.js"></script>
</body>
</html>
Loader
webpack
除了 JavaScript,还可以通过loader
引入任何其他类型的文件,例如 CSS、图片等。
如果一个源文件需要多步转换,就通过多个 Loader 链式顺序执行实现,执行顺序从右到左。
1、打包图片,先安装 loader,然后再配置打包规则
npm install url-loader -D
// webpack.config.js
const path = require('path');
module.exports = {
mode: 'development',// 默认值为 production
// JavaScript 执行入口文件
entry: {
main: './src/index.js'
},
module: {
rules: [
// 配置打包图片 loader 规则
{
test: /\.(jpg|png|gif)$/,
use: {
loader: 'url-loader',
options: {
name: '[name].[ext]', // 打包后图片命名规则
outputPath: 'images/', // 输出路径
limit: 204800, // 小于 200KB 用 url-loader 打包,大于用 file-loader 打包
}
}
}
]
},
output: {
// 将所有依赖的模块合并输出到一个 bundle.js 文件
filename: 'bundle.js',
// 将输出文件都放到 dist 目录下
path: path.resolve(__dirname, './dist'),
}
};
使用url-loader
打包图片,它会将图片转换为base64
字符串加入bundle.js
中,而不是单独生成一个图片文件,适用于较小的图片打包,减少额外的 HTTP 请求。较大的图片使用file-loader
打包到dist
目录下,减少加载时间。
2、打包静态资源,如 CSS 样式文件
npm install style-loader css-loader -D
npm install sass-loader node-sass -D
npm install postcss-loader -D
npm install autoprefixer -D
// webpack.config.js 相关代码片段
module: {
rules: [
{
test: /\.(css|scss)$/,
use: [
'style-loader',
// 'css-loader',
{
loader: 'css-loader',
options: {
importLoaders: 2, // 在 css-loader 前应用的 loader 的数量,确保每个样式文件能通过所有 loader 编译
modules: true, // 开启 CSS 模块化打包
}
},
'sass-loader',
'postcss-loader', // 可为 transform 等样式自动添加厂商前缀
], // 执行顺序从右到左
}
]
}
postcss-loader
可为 transform 等样式自动添加厂商前缀,使用前需要新建一个postcss.config.js
文件。
// postcss.config.js
module.exports = {
plugins: [
require('autoprefixer')
]
};
// postcss.config.js 在工作项目中的写法
module.exports = {
plugins: {
autoprefixer: {}
}
};
3、打包字体图标文件
npm install file-loader -D
// webpack.config.js 相关代码片段
module: {
rules: [
{
test: /\.(eot|ttf|svg)$/,
use: {
loader: 'file-loader',
}
}
]
}
Plugin
loader
用于转换某些类型的模块,而插件则可以用于执行范围更广的任务。包括:打包优化,资源管理,注入环境变量。
1、使用html-webpack-plugin
打包时自动生成 HTML 文件。
html-webpack-plugin
会在打包结束后,自动生成一个 HTML 文件,并把打包生成的 JS 自动引入到这个 HTML 文件中。
// webpack.config.js 相关代码片段
plugins: [
new HtmlWebpackPlugin({
template: 'src/index.html', // 以 src 下的这个文件为模板生成
}),
],
2、clean-webpack-plugin
在打包之前,删除 dist 目录下所有文件。
3、通过Plugin
将注入bundle.js
文件里的 CSS 提取到单独的文件中。
npm i -D extract-text-webpack-plugin
const path = require('path');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
module.exports = {
mode: 'development',
devtool: 'source-map',
// JavaScript 执行入口文件
entry: {
main: './src/index.js'
},
output: {
// 将所有依赖的模块合并输出到一个 bundle.js 文件
filename: 'bundle.js',
// 将输出文件都放到 dist 目录下
path: path.resolve(__dirname, './dist'),
},
module: {
rules: [
// 配置打包 CSS 的 loader 规则
{
// 用正则去匹配要用该 loader 转换的CSS文件
test: /\.css$/,
loaders: ExtractTextPlugin.extract({
// 转换 .css 文件需要使用的 Loader
use: ['css-loader'],
})
}
]
},
plugins: [
new ExtractTextPlugin({
// 从 .js 文件中提取出来的 .css 文件的名称
filename: `[name]_[contenthash:8].css`,
}),
]
};