初始化项目
新建一个项目文件夹,在终端打开,执行
之后,会在项目根目录下出现一个 package.json
文件。
然后在项目根目录下新建 src
文件夹,在此文件夹下新建 main.js
入口文件和 index.html
模板文件。
1 2 3 4 5
| - project - src - main.js - index.html - package.json
|
安装 webpack
1
| npm i webpack-cli webpack webpack-dev-server
|
- webpack:webpack 的核心模块;
- webpack-cli:使得我们可以通过命令行参数运行 webpack;
- webpack-dev-server:可以启动一个本地 HTTP 服务,支持代码热更新,其配置在
webpack.config.js
的 devServer
中。
配置 webpack
在项目根目录下新建 webpack.config.js
文件,添加如下代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| const path = require("node:path");
module.exports = { mode: process.env.NODE_ENV, entry: "./src/main.js", output: { path: path.resolve(__dirname, "dist"), filename: "[name].[hash:8].js", clean: true }, devServer: { port: 8080, host: "0.0.0.0", hot: true, open: true, proxy: { "/api": { target: "http://localhost:5000", pathRewrite: { "^/api": "" } } } } }
|
配置 package.json
1 2 3 4 5 6
| { "scripts": { "dev": "webpack-dev-server --mode development", "build": "webpack --config webpack.config.js --mode production" } }
|
我们可以通过 --mode
指定运行环境。
现在可以通过 npm run dev
来启动一个本地服务,通过 npm run build
来打包构建。
我们还可以为不同的环境创建单独的配置文件:
在根目录下新建 scripts 文件夹,在该文件夹下新建三个配置文件:
1 2 3 4
| - scripts - webpack.base.js - webpack.dev.js - webpack.prod.js
|
webpack.dev.js
和 webpack.prod.js
怎么继承 webpack.base.js
中的配置呢?可以使用 webpack-merge
合并配置文件:
1 2 3 4 5 6 7 8 9 10 11
|
const path = require('path')
module.exports = { entry: path.resolve(__dirname, '../src/main.js'), output: { path: path.resolve(__dirname, '../dist'), filename: '[name].[hash:8].js' } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14
|
const { merge } = require('webpack-merge') const base = require('./webpack.base.js')
module.exports = merge(base, { mode: 'development', devServer: { open: true, port: 8080, host: "0.0.0.0", hot: true }, })
|
1 2 3 4 5 6 7 8
|
const { merge } = require('webpack-merge') const base = require('./webpack.base.js')
module.exports = merge(base, { mode: 'production', })
|
现在 package.json 中的配置如下:
1 2 3 4 5 6
| { "scripts": { "dev": "cross-env NODE_ENV=development webpack server -c scripts/webpack.dev.js", "build": "cross-env NODE_ENV=production webpack -c scripts/webpack.prod.js" } }
|
使用 NODE_ENV=
来设置环境变量,为了在不同的平台上都能使用,我们使用 cross-env
来兼容,这样在不同环境下也能正确获取环境变量。
配置 html 插件
当我们启动服务后会发现,之前创建的模板文件并没有被引用。这时就需要一个插件让 webpack 引用我们自定义的模板文件,并将打包后的出口文件自动插入到模板文件中。
1
| npm i html-webpack-plugin
|
配置 webpack:
1 2 3 4 5 6 7 8 9 10 11 12 13
| const HtmlWebpackPlugin = require("html-webpack-plugin");
module.exports = { plugins: [ new HtmlWebpackPlugin({ template: "./src/index.html", filename: "index.html", inject: "body" }) ] }
|
安装 Babel
babel 的作用就是将 es6/esnext 转为 es5,使得代码能够在各个浏览器中运行。
1
| npm i @babel/core @babel/preset-env babel-loader
|
- @babel/core:babel 的核心包;
- @babel/preset-env:将 es6+ 语法转为 es5 的预设;
- babel-loader:将 babel 与 webpack 关联起来。
配置 babel
在项目根目录下新建 .babelrc
文件,添加如下内容:
1 2 3
| { "presets": ["@babel/preset-env"] }
|
配置 webpack:
1 2 3 4 5 6 7 8 9 10 11 12
| module.exports = { module: { rules: [ { test: /\.js$/, use: "babel-loader", exclude: /node_modules/, include: /src/ } ] } }
|
加载 css
webpack 默认是不处理 css 的,需要安装两个 loader:
1
| npm i style-loader css-loader
|
- style-loader:将 css 添加到 style 标签中,并插入到 html;
- css-loader:解析 css 文件的 import 导入方式,以及 url() 引入方式。
配置 webpack:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| module.exports = { module: { rules: [ { test: /\.js$/, use: "babel-loader", exclude: /node_modules/, include: /src/ }, { test: /\.css$/, use: [ { loader: "style-loader" }, { loader: "css-loader" } ] } ] } }
|
注意: loader 的加载顺序是从右到左(从后往前)的,也就是先支持 import 导入再去插入到 style 标签,如果反了,逻辑也就反了。
加载图片或文件
如果我们直接将图片的路径或 import 导入的变量赋值给 img 标签的 src 属性,会报错无法加载文件。
这时需要安装对应的 loader 来解决:file-loader 或 url-loader。
url-loader 包含了 file-loader,它通过限定一个图片的大小(limit),来判断是否采用编码的方式。小于 limit 的时候使用 base64 进行压缩,大于则使用 file-loader 变成路径。
这里选择 file-loader:
配置 webpack:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| module.exports = { module: { rules: [ { test: /\.js$/, use: "babel-loader", exclude: /node_modules/, include: /src/ }, { test: /\.css$/, use: [ { loader: "style-loader" }, { loader: "css-loader" } ] }, { test: /\.(png|jpe?g|gif)$/i, loader: "file-loader", options: { name: "[name].[ext]", outputPath: "./img" } } ] } }
|
配置 ts
1
| npm i typescript ts-loader @babel/preset-typescript
|
- typescript:TS 的主要引擎;
- ts-loader:转译 ts -> js,并打包;
- @babel/preset-typescript:与 ts-loader 作用相同,但是能够加快打包速度。
既然 @babel/preset-typescript 与 ts-loader 作用相同,且打包速度更快,那为什么还要用 ts-loader 呢?
因为 ts-loader 在内部是调用了 TypeScript 的官方编译器 tsc,会提供完整的报错信息, 而 @babel/preset-typescript 有的时候会无法提供完整的报错信息和类型提示。
1 2 3 4 5 6 7 8 9 10 11 12 13
|
module.exports = { module: { rules: [ { test: /\.tsx?$/, exclude: /node_modules/, use: "ts-loader" } ] } }
|
1 2 3 4 5
|
{ "presets": ["@babel/preset-env", "@babel/preset-typescript"] }
|