webpack
# webpack
以前我们引用外部资源都是用 <script> 标签引入
<script src='vue.js'></script>
- 引用了没有使用 浪费资源
- 没有引用 并创建实例 报错不明显 并且 网页无法加载
- 引用太多笼统
现在我们使用 webpack 我们选择直接使用 关键字 import
import 'vue' from './vue'
并拥有导包,构建等强大的功能
https://webpack.docschina.org/
# webpack 入门
# 引用
import bar from './bar.js';
# 导出
export default function bar() {
//
}
2
3
# 安装
# 生成的默认的 package.json
在项目目录下
npm init -y
# 安装 webpack
npm install --save-dev webpack-cli webpack
# 生成 main.js 打包
.\node_modules\.bin\webpack
# 修改 package.json 简化打包命令
//修改"script中的对象"
"scripts":{
"build":".\node_modules\.bin\webpack" //也可以直接写为 "build":"webpack" build自定义名称
}
2
3
4
#之后我们可以使用简化命令打包了
npm run build
2
# 还有一种方法是 package.json 中的 script 为空,会自动查找项目中的 webpack
# 然后用以下代码打包
npx webpack
2
之后我们在 index 中直接加载 main.js 就好了,webpack 已经把 webpack 文件夹中的打包了
<script src='main.js'></script>
# webpack.config.js 配置 代码分离
# 打包的入口
设置预要打包的文件,webpack 会根据里面的内容逐层引入
module.exports = {
entry: '要打包的文件',
}
2
3
# 打包的出口
设置打包后的代码存放的路径
module.exports = {
output: {
filename: 'main.js', //打包后的文件名,相对路径
path: path.resolve(__dirname, 'dist'),
// 存放到当前项目的dist目录,必须得是一个绝对路径,否则报错
//path.resovle(__dirname,'dist') 获取当前文件所属目录的绝对路径再拼接后面的
}
}
2
3
4
5
6
7
8
# 打包模式
developmemt: 开发环境构建,编译速度快,没有压缩
production: 生产环境构建,编译速度慢,质量比较好,压缩体积
module.exports = {
entry: '要打包的文件',
output: {
filename: 'main.js', //打包后的文件名,相对路径
path: path.resolve(__dirname, 'dist'),
// 存放到当前项目的dist目录,必须得是一个绝对路径,否则报错
//path.resovle(__dirname,'dist') 获取当前文件所属目录的绝对路径再拼接后面的
},
mode:'development' //打包模式,默认为生产环境
}
2
3
4
5
6
7
8
9
10
# 打包 CSS
webpack 本身只嫩理解 JavaScript 和 JSON 文件
需要安装 style-loader 和 css-loader
npm install --save-dev style-loader css-loader
并在 module.exports 中追加以下代码,并打包成为 JavaScript 模块中
module: {
rules: [
// 当匹配到css文件的时候,使用style-loader和css-loader处理,自动插入到index中<head>里面
{
test: /\.css$/i,
use: ['style-loader', 'css-loader'],
},
],
},
2
3
4
5
6
7
8
9
其他类型文件模块更多请查询官方手册 https://webpack.docschina.org/loaders/
# 打包 less
安装
npm install less less-loader --save-dev
追加 module 对象
rules: [
{
test: /\.less$/i,
loader: [ 'style-loader','css-loader', 'less-loader']
//1. less-loader 把less 编译为 css
//2. css-loader 把css 转为 JavaScript 模块
//3. style-loader 在代码运行期间把css 插入页面的head中
},
2
3
4
5
6
7
8
# 打包图片
追加到 module webpack5 内置这个 loader
{
test: /\.(png|svg|jpg|jpeg|gif)$/i,
type: 'asset/resource',
},
2
3
4
引用
import Icon from './icon.png';
// 将图像添加到我们已经存在的 div 中。
const myIcon = new Image();
myIcon.src = Icon;
element.appendChild(myIcon);
2
3
4
5
6
7
8
或者打 index 也打包
# 打包网页
安装模块
npm install --save-dev html-webpack-plugin
追加 moudule 文件属性
plugins: [
new HtmlWebpackPlugin({
title: '自定义名称', // 自动生成一个新的html文件 并且自动引用打包的js文件
}),
]
2
3
4
5
plugins: [
new HtmlWebpackPlugin({
title: './index.html', // 基于我们指定的html生成一个打包后的html,不用引用打包的js文件,打包后webpack会自动导入
}),
]
2
3
4
5
# 打包字体
追加 moudule 文件属性
{
test: /\.(woff|woff2|eot|ttf|otf)$/i,
type: 'asset/resource',
},
2
3
4
# webpack 支持好几种模块
- ECMAScript 6 模块
- CommonJS 模块
- node
- AMD 模块
# 自动清除 dist 目录
打包的过程并不会清除原来原有的文件,如有相同文件则覆盖
module.exports = {
output: {
clean: true, // 我们只需要在output中追一个参数既可 每次打包自动清除dist目录
},
};
2
3
4
5
6
7
# ES6 转 ES5
IE 中不支持 ES6 某些语法 所以要转为 ES5
babel 是一款专门将 ES6 转 ES5 的 编译工具
1. 安装
# 如果已经安装过webpack,把后面的webpack去掉
npm install -D babel-loader @babel/core @babel/preset-env webpack
2
2. 追加 module
{
test: /\.m?js$/,
exclude: /(node_modules|bower_components)/,
use: {
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env']
}
}
}
2
3
4
5
6
7
8
9
10
# API 兼容处理
Babel 默认只能转换基本的 ESC 语法 如:const let 箭头函数 解构赋值
它不会处理 ECMAScript 6 中 新增的 API 方法,如数组中的 includes 方法 字符串的 raw 方法
https://www.babeljs.cn/docs/babel-polyfill
安装
npm install --save @babel/polyfill
在 webpack.config 中 module.export 追加
module.exports = {
entry: ["@babel/polyfill", "./app/js"],
};
2
3
# 开启缓存
babel 打包非常耗时,建议开启缓存用以提高打包的效率
{
test: /\.m?js$/,
exclude: /(node_modules|bower_components)/,
use: {
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env'],
cacheDirectory:true // 开启缓存
}
}
}
2
3
4
5
6
7
8
9
10
11
# Using source maps 源代码地图导航
我们打包后的调试显示的行数与未打包的文件行数不匹配,我们可以添加源代码地图导航
module.exports = {
devtool: 'inline-source-map', //追加,源代码地图导航
}
2
3
inline-source-map 把 source-map 数据和打包结果 存储在同一文件下,不太推荐,体积过大
source-map: 把 source-map 数据 生成到独立的.map 文件中
module.exports = {
devtool: 'source-map',
}
2
3
# watch 监听自动打包
当项目中有修改后自动打包
在 packge.json 文件中追加
"scripts":{
"build-watch":"自定义名称 --watch --config webpack.config.js"
}
2
3
然后打包一下
npm run build-watch
# webpack-dev-server 监听自动打包并自动刷新
开启一个 web 服务器,当项目中有修改后自动打包并自动刷新浏览器
modle.experts = {
devServer: {
contentBase: './dist', // devServer服务监听这个打包目录
},
}
2
3
4
5
并在 packge.json 追加
"start": "webpack serve --open --config webpack.config.js", //--open 是自动打开浏览器 可以省参数 --config webpack.config.js 如果配置项为webpack.config.js则不需要这个
# 热更新
webpack-dev-server 默认是刷新整个页面实现更新。我们有一种更好的方式 热更新,可以在不刷新页面的情况下更新内容变化
只需要在 devserver 中添加 hot:true 即可
modle.experts = {
devServer: {
contentBase: './dist',
hot:true // 开启热更新
},
}
2
3
4
5
6
# 打包 Vue
项目中安装
npm i vue
在 webpack 安装 vue-loader 和 vue-template-compiler vue 打包模块
npm install -D vue-loader vue-template-compiler
在 webpack 配置中引用 https://vue-loader.vuejs.org/zh/guide/#% E6%89%8B% E5%8A% A8% E8% AE% BE% E7% BD% AE
const { VueLoaderPlugin } = require('vue-loader')
// 并在module.exports中追加
plugins: [
// 请确保引入这个插件!
new VueLoaderPlugin()
]
// 并在rules添加文件匹配规则
{
test: /\.vue$/,
loader: 'vue-loader'
}
2
3
4
5
6
7
8
9
10
11
12
13
- 在 webpack 中的 Vue 组件 import 要加上后缀,无法像 cli 中忽略后缀
- 在 vue 使用 less 也需要进行配置
- 把 loader 换成 use:['style-loader','css-loader', 'less-loader','vue-loader'] 顺序是从后到前
# resolve.extensions 按顺序加载解析这些后缀名
module.exports = {
//...
resolve: {
// extensions: ['.js', '.json', '.wasm'], // 默认值
extensions:['.js', '.json','.vue','.css']
},
};
2
3
4
5
6
7
配置完后 import 时扩展名可以忽略 按你自定义的顺序来解析 从后到前
# 在 webpack 中不能使用 @定向于 src 文件夹
我们可以使用 webpack 中的 resolve.alias 创建 import 或 require 的别名,来确保模块引入变得更简单
resolve: {
alias: {
//别名 : 路径 自定义名称是特殊字符要用引号括起
'@': path.resolve(__dirname, './src'),
},
},
2
3
4
5
6
# 使用 ESLint
ESLint 是用于 JavaScript 代码格式校验工具
- 安装
npm install eslint-loader --save-dev
npm install eslint --save-dev
2
- 追加 webpack.json
module.exports = {
// ...
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
loader: 'eslint-loader',
options: {
// eslint options (if necessary)
},
},
],
},
// ...
};
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
如果使用了 ES6 转 ES5 模块 会与 ESLint 产生冲突,我们想要优先把 ESLint 校验放在前面,但配置选项不是按照书写顺序来执行的,所以我们需要把 test 为 js 文件的 loader 配置 换 use 配置,use:['babel-loader', ,'eslint-loader']
module.exports = {
// ...
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: ['babel-loader', 'eslint-loader'],
},
],
},
// ...
};
2
3
4
5
6
7
8
9
10
11
12
13
也可拆分书写
module.exports = {
// ...
module: {
rules: [
{
enforce: 'pre', // 强制 提前
test: /\.js$/,
exclude: /node_modules/,
loader: 'eslint-loader',
},
{
test: /\.js$/,
exclude: /node_modules/,
loader: 'babel-loader',
},
],
},
// ...
};
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 选择 ESLint 的代码规范
打开 eslint 命令符
.\node_modules\.bin\eslint.cmd --init
# 或者 npx eslint --init 详情简写请看 安装中的修改package.json 简化打包命令
2