参考文章:《How to Create a React app from scratch using Webpack 4 》 write by Linh Nguyen Mycss
npm init -y
npm i webpack webpack-cli -D
命令解释html
以上命令等同于node
npm install webpack webpack-cli --save-dev
console.log("hello");
{ "name": "translation-tool-webpack-react", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "start": "webpack --mode development", "build": "webpack --mode production" }, "keywords": [], "author": "", "license": "ISC", "devDependencies": { "webpack": "^4.41.2", "webpack-cli": "^3.3.10" } }
Webpack4 如今有2中模式,development和production, 当运行
npm run start
或者 npm start
的时候,会在dist文件夹下建立一个main.js, 会包含咱们写在src中的代码,效果如图:
react
若是运行npm run build
那么输出的代码如图所示
webpack
若是想要使用React来进行编码,须要使用Babel, 它会将ES6转换成ES5,由于目前并非全部的浏览器都支持ES6,例如IEweb
npm i react react-dom -S
命令解释:npm
npm i babel-core babel-loader@7 babel-preset-env, babel-preset-react -D
命令解释json
module.exports = { module: { rules: [ { test: /\.js$/, exclude: /node_modules/, use: { loader: "babel-loader" } } ] } }
{ "preset": ["env", "react"] }
import React from 'react'; import ReactDOM from 'react-dom'; const Index = () => { return <div>Hello React!</div> }; ReactDOM.render(<Index />, document.getElementById("index));
<!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>React and Webpack4</title> </head> <body> <section id="index"></section> </body> </html>
安装html-webpack-plugin并在webpack.confg.js中配置它。 这个插件会生成一个html网页,插入一个<script>
,将文件生成在dist/index.html并轻量化。数组
npm i html-webpack-plugin -D
const HtmlWebPackPlugin = require("html-webpack-plugin"); const htmlPlugin = new HtmlWebPackPlugin({ template: "./src/index.html", filename: "./index.html" }); module.exports = { module: { rules: [ { test: /\.js$/, exclude: /node_modules/, use: { loader: "babel-loader" } } ] }, plugins: [htmlPlugin] };
plugin的配置也能够写在module里面:
plugins: [ new HtmlWebPackPlugin({ template: "./src/index.html", filename: "./index.html" }); ]
可是更推荐第一种,这样可读性比较好。浏览器
template
的值是生成html文件时的模板html文件。 此时运行命令npm run start
或者npm start
, 能够看到index.html生成:
此时打开dist下的index.html文件,会看到浏览器中显示"Hello React"。
每次修改后须要从新编译再看效果是很麻烦的事情,所以,咱们可使用webpack-dev-server模块来让webpack监听代码的改动,并及时更新组件
安装webpack-dev-server做为开发依赖
npm i webpack-dev-server -D
而后修改package.json的start命令,以下面所示:
{ "name": "translation-tool-webpack-react", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "start": "webpack-dev-server --mode development --open --hot", "build": "webpack --mode production" }, "keywords": [], "author": "", "license": "ISC", "devDependencies": { "babel-core": "^6.26.3", "babel-loader": "^7.1.5", "babel-preset-env": "^1.7.0", "babel-preset-react": "^6.24.1", "css-loader": "^3.2.0", "html-webpack-plugin": "^3.2.0", "style-loader": "^1.0.0", "webpack": "^4.41.2", "webpack-cli": "^3.3.10", "webpack-dev-server": "^3.9.0" }, "dependencies": { "react": "^16.11.0", "react-dom": "^16.11.0" } }
如今运行npm run start
或者npm start
命令,会自动打开浏览器并打开页面localhonst:8080 (--open 命令的效果),如今页面会根据代码的变更热加载。 若是不想每次变动整个页面,只变动有变化的组件,可使用--hot命令(详情参考Hot Module Replacement)
当咱们在React组件中导入css文件时,会须要css-loader来加载它们。当css加载完毕,还须要style-loader来将它们插入到咱们的DOM中:添加一个<style>
标签到HTML页面<head>
中
npm i css-loader style-loader -D
2.更新webpack.config.js:
const HtmlWebPackPlugin = require("html-webpack-plugin"); const htmlWebpackPlugin = new HtmlWebPackPlugin({ template: "./src/index.html", filename: "./index.html" }); module.exports = { module: { rules: [ { test: /\.js$/, exclude: /node_modules/, use: { loader: "babel-loader" } }, { test: /\.css$/, use: ["style-loader", "css-loader"] } ] }, plugins: [htmlWebpackPlugin] };
注意这里的loader的添加顺序。 咱们须要先解析CSS文件,而后在用style-loader加载到DOM。 默认状况下,webpack是从右到左(从数组的最后一位向第一位)加载
使用webpack能够将css模块化,即加载的class name会被限制在使用的组件中,从而限制其做用范围。
const HtmlWebPackPlugin = require("html-webpack-plugin"); const htmlWebpackPlugin = new HtmlWebPackPlugin({ template: "./src/index.html", filename: "./index.html" }); module.exports = { module: { rules: [ { test: /\.js$/, exclude: /node_modules/, use: { loader: "babel-loader" } }, { test: /\.css$/, use: [ { loader: "style-loader" }, { loader: "css-loader", options: { modules: true, importLoaders: 1, localIdentName: "[name]_[local]_[hash:base64]", sourceMap: true, minimize: true } } ] } ] }, plugins: [htmlWebpackPlugin] };
咱们在设置配置的时候,每一个loader都变成了一个对象,option配置的解释:
有了模块化,咱们就不用担忧同一个class name在整个项目中冲突的问题,只须要考虑同一个component中如何定义class name便可。
配置webpack的resolve,能够定义加载文件的规则,例如,不想每次导入的时候都精确到文件以及后缀名,能够修改webpack.config.js以下:
const HtmlWebPackPlugin = require("html-webpack-plugin"); const htmlPlugin = new HtmlWebPackPlugin({ template: "./src/index.html", filename: "./index.html" }) module.exports = { module: { rules: [{ test: /\.js$/, exclude: /node_modules/, use: { loader: 'babel-loader' } }, { test: /\.jsx$/, exclude: /node_modules/, use: { loader: 'babel-loader' } }, { test: /\css$/, use: [{ loader: "style-loader", }, { loader: "css-loader", options: { modules: true, importLoaders: 1, localIdentName: "[name]_[local]_[hash:base64]", sourceMap: true, minimize: true } } ] } ] }, plugins: [htmlPlugin], resolve: { extensions: ['.js', '.jsx', '.json'] }