參考文章:《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'] }