Webpack 4(三)
Webpack 开发一个 Loader
开发一个 markdown-loader
// src/about.md
# 关于我
我是 robert, 一名技术爱好者~
import about from './about.md'
console.log(about)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Webpack - 开发一个 Loader</title>
</head>
<body>
<script src="dist/bundle.js"></script>
</body>
</html>
yarn add html-loader@0.5.5 --dev
// ./markdown-loader.js
const marked = require('marked')
// Loader 负责资源文件从输入到输出的转换
// Loader 实际上是一种管道的概念
// 对于同一个资源可以依次使用多个 Loader
module.exports = source => {
// console.log(source)
// return 'console.log("hello ~")'
const html = marked(source)
// return html
// return 'module.exports = "${html}"'
// JSON.stringify 防止 html 中的换行符,内部引号拼接一起,造成错误
// return `module.exports = ${JSON.stringify(html)}`
// return `export default ${JSON.stringify(html)}`
// 返回 html 字符串交个下一个 loader 处理
return html
}
const path = require('path')
module.exports = {
mode: 'none',
entry: './src/main.js',
output: {
filename: 'bundle.js',
path: path.join(__dirname, 'dist'),
publicPath: 'dist/'
},
module: {
rules: [
{
test: /.md$/,
use: [
'html-loader',
'./markdown-loader'
]
}
]
}
}
Loader 工作原理
Loader 负责资源文件从输入到输出的转换,Loader 实际是一种管道的概念,可以将此次 Loader 的结果交给下一个 Loader 去处理,对于同一个资源可以依次使用多个 Loader。
管道工作后的结果必须是一段 JS 代码。




Webpack 插件机制介绍
插件可以增强 Webpack 自动化能力
- 清除 dist 目录
- 拷贝静态文件至输出目录
- 压缩输出代码
自动清除输出目录插件
插件:clean-webpack-plugin
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Webpack Plugins</title>
</head>
<body>
<script src="dist/bundle.js"></script>
</body>
</html>
// ./package.json
{
"name": "03-clean-webpack-plugin",
"version": "0.1.0",
"main": "index.js",
"author": "",
"license": "MIT",
"scripts": {
"build": "webpack"
},
"devDependencies": {
"clean-webpack-plugin": "^3.0.0",
"css-loader": "^3.2.0",
"file-loader": "^4.2.0",
"style-loader": "^1.0.0",
"url-loader": "^2.2.0",
"webpack": "^4.40.2",
"webpack-cli": "^3.3.9"
}
}
// ./webpack.config.js
const path = require('path')
const { CleanWebpackPlugin } = require('clean-webpack-plugin')
module.exports = {
mode: 'none',
entry: './src/main.js',
output: {
filename: 'bundle.js',
path: path.join(__dirname, 'dist'),
publicPath: 'dist/'
},
module: {
rules: [
{
test: /.css$/,
use: [
'style-loader',
'css-loader'
]
},
{
test: /.png$/,
use: {
loader: 'url-loader',
options: {
limit: 10 * 1024 // 10 KB
}
}
}
]
},
plugins: [
new CleanWebpackPlugin()
]
}

自动生成 HTML 插件
通过硬编码的方式将 index.html 存放在项目根目录下,存在的问题:
- 项目发布时,要同时发布 src/index.html 和 dist 目录下的打包结果,比较麻烦,同时还要确保 index.html 代码中的引用的 JS 等资源的路径是正确的
- 打包的结果配置发生了变化,index.html 中 script 标签中引用的路径需要手动去修改
解决以上问题的办法:
通过 webpack 输出 HTML 文件,构建过程中 webpack 会自动将打包的 bundle 添加到页面中,HTML 也会输出到 dist 目录,bundle 是自动注入的,所以能确保路径的引用是正常的。
html-webpack-plugin
// package.json
{
"name": "04-html-webpack-plugin",
"version": "0.1.0",
"main": "index.js",
"author": "",
"license": "MIT",
"scripts": {
"build": "webpack"
},
"devDependencies": {
"clean-webpack-plugin": "^3.0.0",
"css-loader": "^3.2.0",
"file-loader": "^4.2.0",
"html-webpack-plugin": "^3.2.0",
"style-loader": "^1.0.0",
"url-loader": "^2.2.0",
"webpack": "^4.40.2",
"webpack-cli": "^3.3.9"
}
}
// webpacck.config.js
const path = require('path')
const { CleanWebpackPlugin } = require('clean-webpack-plugin')
const HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
mode: 'none',
entry: './src/main.js',
output: {
filename: 'bundle.js',
path: path.join(__dirname, 'dist'),
// publicPath: 'dist/'
},
module: {
rules: [
{
test: /.css$/,
use: [
'style-loader',
'css-loader'
]
},
{
test: /.png$/,
use: {
loader: 'url-loader',
options: {
limit: 10 * 1024 // 10 KB
}
}
}
]
},
plugins: [
new CleanWebpackPlugin(),
// 用于生成 index.html
new HtmlWebpackPlugin({
title: 'Webpack Plugin Sample',
meta: {
viewport: 'width=device-width'
},
template: './src/index.html'
}),
// 用于生成 about.html
new HtmlWebpackPlugin({
filename: 'about.html'
})
]
}
// src/index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Webpack</title>
</head>
<body>
<div class="container">
<h1><%= htmlWebpackPlugin.options.title %></h1>
</div>
</body>
</html>

CopyWebpackPlugin
CopyWebpackPlugin 可将单个文件或整个目录复制到构建目录。
yarn add copy-webpack-plugin@5.0.4 --dev
const path = require('path')
const { CleanWebpackPlugin } = require('clean-webpack-plugin')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const CopyWebpackPlugin = require('copy-webpack-plugin')
module.exports = {
mode: 'none',
entry: './src/main.js',
output: {
filename: 'bundle.js',
path: path.join(__dirname, 'dist'),
// publicPath: 'dist/'
},
module: {
rules: [
{
test: /.css$/,
use: [
'style-loader',
'css-loader'
]
},
{
test: /.png$/,
use: {
loader: 'url-loader',
options: {
limit: 10 * 1024 // 10 KB
}
}
}
]
},
plugins: [
new CleanWebpackPlugin(),
// 用于生成 index.html
new HtmlWebpackPlugin({
title: 'Webpack Plugin Sample',
meta: {
viewport: 'width=device-width'
},
template: './src/index.html'
}),
// 用于生成 about.html
new HtmlWebpackPlugin({
filename: 'about.html'
}),
new CopyWebpackPlugin([
// 'public/**'
'public'
])
]
}
浙公网安备 33010602011771号