Bundling
当运行npm run build的时候,webpack将源代码转化为单个的文件

新建一个项目目录解构如下
package.json
{"name": "webpack-part7","version": "0.0.1","description": "practising webpack","scripts": {},"license": "MIT"}
安装webpack
npm install --save-dev webpack webpack-cli
webpack.config.js添加配置
entry属性是绑定应用的入口点
const path = require('path')const config = {entry: './src/index.js',output: {path: path.resolve(__dirname, 'build'),filename: 'main.js'}}module.exports = config
package.json添加script
"scripts": {"build": "webpack --mode=development"},
在src/index.js添加一些代码,新建App.js并添加一些代码,执行命令**npm run build**,在build目录会生成main.js文件, 里面包含了index.js和App.js中转译后的代码
Bundling React
安装react
npm install react react-dom
写一些react代码后,build,报错,提示需要一个合适的loader
Loaders
webpack默认只能转译纯javascript脚本,要转移react,需要添加一个loader
在webpack.config.js中添加module rules
const config = {entry: './src/index.js',output: {path: path.resolve(__dirname, 'build'),filename: 'main.js',},module: {rules: [{test: /\.js$/,loader: 'babel-loader',options: {presets: ['@babel/preset-react'],},},],},}
- test属性指定loader用于.js结尾的文件
- loader属性指定处理这个文件的loader是babel-loader
- options属性用于传递参数
安装loader为开发依赖
npm install @babel/core babel-loader @babel/preset-react --save-dev
安装完成后再build就不会报错了,转译后的文件可以直接用浏览器打开查看效果
如果代码中使用了async/await, 需要安装另一个依赖: @babel/polyfill
npm install @babel/polyfill
Transpilers
将代码从一种 JavaScript 形式转换为另一种 JavaScript 形式的过程称为transpiling
ES6以上的JS代码需要转译成ES5
大多数人使用的是@babel/pressing-env插件
它包含使用所有最新特性编写代码并将其转化为兼容 ES5标准的代码所需的所有内容
在配置文件的presets中添加’@babel/preset-env’
{test: /\.js$/,loader: 'babel-loader',options: {presets: ['@babel/preset-env', '@babel/preset-react']}}
安装@babel/preset-env
npm install @babel/preset-env --save-dev
转移后的代码就像这样
var App = function App() {return _react2.default.createElement('div', null, 'hello webpack')};
CSS
加入CSS后build报错
.container {margin: 10;background-color: #dee8e4;}

转译css需要用到css-loader 和 style-loader
css-loader用于加载css文件
style-loader生成并注入一个style元素,css定义最后包含在main.js文件中
{rules: [{test: /\.js$/,loader: 'babel-loader',options: {presets: ['@babel/preset-react', '@babel/preset-env'],},},{test: /\.css$/,use: ['style-loader', 'css-loader'],},];}
安装
npm install style-loader css-loader --save-dev
Webpack-dev-server
当前的工作流非常糟糕,每次修改代码,都要重新build,手动刷新浏览器查看效果
webpack-dev-server 解决了这个问题, 当代码修改时,自动build并刷新页面
安装成开发者依赖
npm install --save-dev webpack-dev-server
在scripts中添加start命令
{// ..."scripts": {"build": "webpack --mode=development","start": "webpack serve --mode=development"},// ...}
在webpack.config.js配置中添加devServer
const config = {entry: './src/index.js',output: {path: path.resolve(__dirname, 'build'),filename: 'main.js',},devServer: {static: path.resolve(__dirname, 'build'),compress: true,port: 3000,},// ...};
webpack-dev-server的转译是在内存中的,而不是在build目录
注意,在build目录中需要添加index.html作为主页
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8" /><title>React App</title></head><body><div id="root"></div><script type="text/javascript" src="./main.js"></script></body></html>
Source maps

当控制台发生错误,点击App.js跳转到调试页面,发现不是我们的源代码
在配置中添加devtool
const config = {entry: './src/index.js',output: {// ...},devServer: {// ...},devtool: 'source-map',// ..};
Minifying the code
在版本4以上的webpack中,只需要将build命令的mode设置为production,就能压缩代码
"scripts": {"build": "webpack --mode=production","start": "webpack serve --mode=development"},
执行命令 npm run build
所有的便笺、甚至不必要的空格和换行符都被删除了,变量名被单个字符替换。
Development and production configuration
实现当在本地使用时,应用使用端口3001中可用的 json-server 作为其后端
而打包时,指定为后端服务器地址
将webpack的配置改成函数形式
const path = require('path');const config = (env, argv) => {return {entry: './src/index.js',output: {// ...},devServer: {// ...},devtool: 'source-map',module: {// ...},plugins: [// ...],}}module.exports = config
定义全局常量backend_url
const path = require('path')const webpack = require('webpack')const config = (env, argv) => {console.log('argv', argv.mode)const backend_url = argv.mode === 'production'? 'https://blooming-atoll-75500.herokuapp.com/api/notes': 'http://localhost:3001/notes'return {entry: './src/index.js',output: {path: path.resolve(__dirname, 'build'),filename: 'main.js'},devServer: {contentBase: path.resolve(__dirname, 'build'),compress: true,port: 3000,},devtool: 'source-map',module: {// ...},plugins: [new webpack.DefinePlugin({BACKEND_URL: JSON.stringify(backend_url)})]}}module.exports = config
使用backend_url
const App = () => {const [counter, setCounter] = useState(0)const [values, setValues] = useState([])const notes = useNotes(BACKEND_URL)// ...return (<div className="container">hello webpack {counter} clicks<button onClick={handleClick} >press</button><div>{notes.length} notes on server {BACKEND_URL}</div></div>)}
在build目录执行如下命令可查看生产版本的效果
npx static-server
Polyfill
IE不支持axios promises和数组的find方法
在应用中添加下列内容,以支持promise
import PromisePolyfill from 'promise-polyfill'if (!window.Promise) {window.Promise = PromisePolyfill}
