webpack
yarn init
yarn add webpack webpack-cli --dev
yarn webpack --version
yarn webpack
webpack.config.js
const path = require('path')
module.exports = {
entry: './src/index.js',
output: {
filename: 'bundle.js',
path: path.join(__dirname, 'output')
}
}
// yarn webpack --mode development
// yarn webpack --mode none
1.webpack资源模块加载
// yarn add css-loader --dev
// yarn add style-loader --dev 把css-loader转换后的结果通过style标签的形式最加到页面上
// yarn add file-loader --dev 文件资源加载器
// yarn add url-loader --dev URL加载器 (小文件转为baseURL)
2.webpack常用加载器分类
- 编译转换类
- 文件操作类
- 代码检查类
3.webpack与es2015
// yarn add babel-loader @babel/core @babel/preset-env --dev
- webpack只是打包工具
- 加载器可以用来编译转换代码
4.webpack加载资源的方式
- 遵循ES Module标准的import声明
- 遵循CommomJS标准的require函数
- 遵循AMD标准的define函数和require函数
- loader加载的非JavaScript也会触发资源加载
- 样式代码中的@import指令和url函数
- HTML代码中图片标签的src属性
// yarn add html-loader --dev
5.webpack核心工作原理
loader机制是webpack的核心
6.webpack开发一个loader
// src/about.md
# ZXT
// src/main.js
import about from './about.md'
console.log(about)
// markdown-loader.js 返回一个js
// __webpack_exports__["default"] = ("<h1 id="zxt">ZXT</h1>\n");
const marked = require('marked')
module.exports = source => {
// console.log(source)
// return 'console.log("hello~")'
const html = marked(source)
// return `moudle.exports = ${JSON.stringify(html)}`
return `export default ${JSON.stringify(html)}`
}
// 导出一个html
// (function(module, exports) { module.exports = "export default"<h1 id=\"zxt\">ZXT</h1>\n"";/***/ })
// webpack.config.js
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
7.webpack插件机制
loader专注实现资源模块加载
plugin解决项目中其他自动化工作(清除dist目录、拷贝静态文件到输出目录、压缩代码)
// 清除输出目录
// yarn add clean-webpack-plugin --dev
const { CleanWebpackPlugin } = require('clean-webpack-plugin')
plugins: [
new CleanWebpackPlugin()
]
// webpack 自动生成html插件 加babel插件会报错
// yarn add html-webpack-plugin --dev
// 报错 npm i babel-loader @babel/core @babel/preset-env
// yarn add html-webpack-plugin@3.2.0 --dev
plugins: [
new CleanWebpackPlugin(),
// 用于生成 index.html
new HtmlWebpackPlugin({
title: 'Webpack Plugin Sample', // 设置标题
meta: {
viewport: 'width=device-width'
},
template: './index.html' // 生成html的模板
}),
// 用于生成 about.html
new HtmlWebpackPlugin({
filename: 'about.html'
})
]
// 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>
8.webpack常用插件
// npm i copy-webpack-plugin --dev 会报错
// npm i copy-webpack-plugin@5.0.4 --dev
const CopyWebpackPlugin = require('copy-webpack-plugin')
new CopyWebpackPlugin({
// public/** public下的文件会拷贝到dist
'public'
})
imagemin-webpack
9.webpack开发一个插件
插件通过在生命周期钩子函数中挂载函数实现扩展
// plugin通过钩子机制实现
// 必须是一个函数或是一个包含apply方法的对象
class MyPlugin {
apply(compiler) {
console.log('MyPlugin run')
compiler.hooks.emit.tap('MyPlugin', compilation => {
for (const name in compilation.assets) {
// console.log(name)
// console.log(compilation.assets[name].source())
if (name.endsWith('.js')) {
const contents = compilation.assets[name].source()
// 替换代码中的注释
const withoutComments = contents.replace(//**+*//g, '')
// 覆盖原有内容
compilation.assets[name] = {
source: () => withoutComments,
size: () => withoutComments.length
}
}
}
})
}
}
new MyPlugin()
10.webpack实现监听
"scripts": {
"build": "webpack --watch"
},
11.webpack自动刷新浏览器
// yarn add browser-sync --dev
// 启动 browser-sync dist --files "**/*" 和 webpack --watch
12.webpack dev server
集成[自动编译]和[自动刷新浏览器]等功能
打包的内容会自动存到内存中
// yarn add webpack-dev-server --dev
// yarn webpack-dev-server
// yarn webpack-dev-server --open 自动唤起浏览器
13.Webpack Dev Server静态资源访问
devServer: {
contentBase: '/public' // 额外为开发服务器指定查找资源目录
},
// const CopyWebpackPlugin = require('copy-webpack-plugin') 放在上线前使用
14.Webpack Dev Server 代理API
接口跨域
devServer: {
contentBase: '/public',
// http://localhost:8080/api/users ---> https://api.github.com/api/users
proxy: {
'/api': {
target: 'https://api.github.com',
// http://localhost:8080/api/users ---> https://api.github.com/users
pathRewrite: {
'^api': ''
},
// 不能使用 localhost:8080 作为请求 GitHub 的主机名
changeOrigin: true
},
}
},