This post is created 2 years ago, the content may be outdated.
废话
最近因为有项目需要,开始学习React。第一步是工程环境的搭建,这肯定要用到当下最火的Webpack(才不是装比)。因为是初学,为了更好的理解配置(给自己找事),我没有用脚手架。
Youtube上有一个不错的教学视频,我基本上就是跟着教程照葫芦画瓢。
水一篇文章记录过程,免得过段时间忘了。
安装Webpack
创建Node package:
private回答“是”以免package被发布。
安装Webpack:
1
| yarn add -D webpack webpack-cli
|
修改package.json
,添加为webpack打包命令添加入口:
1 2 3
| "scripts": { "build": "webpack --mode production" }
|
新建./src/index.js
,这是webpack默认的入口文件。
测试
可以先在index.js
里写个HelloWorld:
1
| console.log("Hello Webpack");
|
再运行
应当产出了./dist/main.js
,Webpack安装完成。
安装开发服务器
如果每次修改代码后都要编译部署才能看到效果,效率太感人了。我们需要一个一键运行的开发服务器,并且所有修改都应该立即展现。
1
| yarn add -D webpack-dev-server
|
修改package.json
1 2 3 4
| "scripts": { "start": "webpack-dev-server --mode development --open", "build": "webpack --mode production" }
|
以后用yarn start
就能启动开发服务器了,默认端口8080。
安装React
添加React依赖:
1
| yarn add -D react react-dom
|
现在JS里面可以导入了:
1
| import React from "react";
|
其它第三方库的安装以此类推。
添加Babel
为了让过气浏览器也能运行ES6,用babel编译代码。
添加Babel依赖:
1
| yarn add -D @babel/core babel-loader @babel/preset-env
|
修改package.json
1 2 3 4
| "scripts": { "start": "webpack-dev-server --mode development --open", "build": "webpack --mode production" }
|
Babel添加React支持:
1
| yarn add -D @babel/preset-react
|
新建.babelrc
1 2 3
| { "presets": ["@babel/preset-env", "@babel/preset-react"] }
|
新建webpack.config.js
,添加规则把js和jsx文件交给babel-loader处理:
1 2 3 4 5 6 7 8 9 10 11 12 13
| module.exports = { module: { rules: [ { test: /\.(js|jsx)$/, exclude: /node_modules/, use: { loader: "babel-loader" } } ] } };
|
使用Hash区分文件版本
浏览器缓存/CDN缓存的同步很蛋疼,JS、CSS等文件名添加hash就可以确保index所引用的文件版本正确。index.html的缓存时长可以调得相对小一些。
修改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
| const isDevelopment = process.env.NODE_ENV === 'development';
module.exports = { module: { entry: { main: "./src/index.js" }, output: { filename: isDevelopment? "[name].js" : "[name].[contenthash].js" }, rules: [ { test: /\.(js|jsx)$/, exclude: /node_modules/, use: [ { loader: "babel-loader" } ] } ] } };
|
这里为了省事用isDevelopment
变量来区分配置,但推荐的做法是使用webpack-merge,并为不同环境分别建立配置文件。
添加HTML支持
新建./src/index.html
:
1 2 3 4 5 6 7 8 9
| <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Hello Webpack</title> </head> <body> </body> </html>
|
添加依赖:
1
| yarn add -D html-webpack-plugin html-loader
|
修改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 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
| const HtmlWebPackPlugin = require("html-webpack-plugin");
const isDevelopment = process.env.NODE_ENV === 'development';
module.exports = { entry: { main: "./src/index.js" }, output: { filename: isDevelopment? "[name].js" : "[name].[contentHash].js" }, module: { rules: [ { test: /\.(js|jsx)$/, exclude: /node_modules/, use: [ { loader: "babel-loader" } ] }, { test: /\.html$/, use: [ { loader: "html-loader", options: { minimize: true } } ] } ] }, plugins: [ new HtmlWebPackPlugin({ template: "./src/index.html", filename: "./index.html" }) ] };
|
添加SASS/SCSS支持
安装相关loader和plugin:
1
| yarn add -D node-sass sass-loader style-loader css-loader mini-css-extract-plugin
|
修改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 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89
| const HtmlWebPackPlugin = require("html-webpack-plugin"); const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const isDevelopment = process.env.NODE_ENV === 'development';
module.exports = { entry: { main: "./src/index.js" }, output: { filename: isDevelopment? "[name].js" : "[name].[contenthash].js" }, module: { rules: [ { test: /\.(js|jsx)$/, exclude: /node_modules/, use: [ { loader: "babel-loader" } ] }, { test: /\.html$/, use: [ { loader: "html-loader", options: { minimize: true } } ] }, { test: /\.module\.s[ac]ss$/, use: [ isDevelopment ? 'style-loader' : MiniCssExtractPlugin.loader, { loader: 'css-loader', options: { modules: true, sourceMap: isDevelopment } }, { loader: 'sass-loader', options: { sourceMap: isDevelopment } } ] }, { test: /\.s[ac]ss$/, exclude: /\.module.s([ac]ss)$/, use: [ isDevelopment ? 'style-loader' : MiniCssExtractPlugin.loader, { loader: 'css-loader', options: { modules: false, sourceMap: isDevelopment } }, { loader: 'sass-loader', options: { sourceMap: isDevelopment } } ] } ] }, resolve: { extensions: ['.js', '.jsx', '.scss'] }, plugins: [ new HtmlWebPackPlugin({ template: "./src/index.html", filename: "./index.html" }), new MiniCssExtractPlugin({ filename: isDevelopment ? '[name].css' : '[name].[hash].css', chunkFilename: isDevelopment ? '[id].css' : '[id].[hash].css' }) ] };
|
use参数的数组执行顺序是从后向前。style-loader
会将CSS注入DOM,而mini-css-extract-plugin
会将所有CSS打包成一个独立文件,并在index.html的head中引用。
添加静态资源支持
添加依赖:
编辑webpack.config.js
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| rules: [ { test: /\.(svg|png|jpg|jpeg|webp|bmp|gif)$/, use: [ { loader: "file-loader", options: { name: isDevelopment ? "[name].[ext]" : "[name].[hash].[ext]", outputPath: "assets/img" } } ] }, ]
|
自动清理编译目录
编辑webpack.config.js
:
1 2 3 4 5 6
| output: { clean: true, filename: isDevelopment? "[name].js" : "[name].[contenthash].js" },
|
参考资料