項目初始化 $ npm init
復制代碼 安裝webpack $ npm install --save-dev
復制代碼 新建webpack配置文件 在根目錄創建build文件夾,添加一個js文件,命名為webpack.base.conf.js // webpack.base.conf.js 文件
const path = require(
'path' );
const DIST_PATH = path.resolve(__dirname,
'../dist' );
module.exports = {entry: {app:
'./app/index.js' },output: {filename:
"js/bundle.js" ,path: DIST_PATH}
};
復制代碼 使用merge的方式來組織webpack基礎配置和不同環境的配置 $ npm install --save-dev webpack-merge
復制代碼 在build文件夾中再添加一個js文件,命名為 webpack.prod.conf.js // webpack.prod.conf.js 文件
const merge = require(
'webpack-merge' );
const baseWebpackConfig = require(
'./webpack.base.conf' );
module.exports = merge(baseWebpackConfig, {mode:
'production'
});
復制代碼 在根目錄下創建app目錄,然后創建index.js文件 var element =document.getElementById(
'root' );
element.innerHTML =
'hello, world!' ;
復制代碼 在根目錄創建一個public文件夾,然后新建一個index.html文件 // index.html
<!DOCTYPE html>
<html lang=
"en" ><head><meta charset=
"UTF-8" ><title>從零開始搭建react工程</title></head><body><div id=
"root" ></div><script src=
"../dist/js/bundle.js" ></script></body>
</html>
復制代碼 當前項目目錄樹 |- /app|- index.js|- /node_modules|- /public|- index.html|- /build|- webpack.base.conf.js|- webpack.prod.conf.js|- package.json|- package-lock.json
復制代碼 安裝webpack-cli webpack 4.0 版本之后的webpack,已經將webpack命令工具遷移到webpack-cli模塊了,需要安裝 webpack-cli $ npm install --save-dev webpack-cli
復制代碼 package.json文件 scripts屬性配置一個build命令 其值為:webpack --config build/webpack.prod.conf.js,以下是scripts的相關代碼 // package.json
"scripts" : {
"build" :
"webpack --config build/webpack.prod.conf.js" ,
"test" :
"echo \"Error: no test specified\" && exit 1"
},
復制代碼 安裝React $ npm install --save react react-dom
復制代碼 import React from
"react" ;
import ReactDom from
"react-dom" ;ReactDom.render(<h1>hello, world!</h1>,document.getElementById(
"root" )
);
復制代碼 注意 import 屬于ES6規范,因此需要轉譯ES2015+的語法,安裝并配置 babel 以及相關依賴 $ npm install --save-dev babel-loader babel-core babel-preset-env babel-preset-react
復制代碼 根目錄創建.babelrc文件,配置presets. {
"presets" : [[
"env" ,{
"targets" : {
"browsers" : [
"> 1%" ,
"last 5 versions" ,
"ie >= 8" ]}}],
"react" ]
}
復制代碼 // webpack.base.conf.js
const path = require(
'path' );
const APP_PATH = path.resolve(__dirname,
'../app' );
const DIST_PATH = path.resolve(__dirname,
'../dist' );
module.exports = {entry: {app:
'./app/index.js' }, output: {filename:
'js/bundle.js' ,path: DIST_PATH},module: {rules: [{
test : /\.js?$/,use:
"babel-loader" ,include: APP_PATH}]}
};
復制代碼 添加插件 public下的index.html本該自動添加到dist目錄,并且引用資源自動加載到該文件,通過html-webpack-plugin實現這一步 $ npm install html-webpack-plugin --save-dev
復制代碼 webpack.prod.conf.js中配置plugins屬性 const merge = require(
'webpack-merge' );
const baseWebpackConfig = require(
'./webpack.base.conf.js' );
const HtmlWebpackPlugin = require(
'html-webpack-plugin' );module.exports = merge(baseWebpackConfig, {mode:
'production' ,plugins: [new HtmlWebpackPlugin({template:
'public/index.html' ,inject:
'body' ,minify: {removeComments:
true ,collapseWhitespace:
true ,removeAttributeQuotes:
true },})]
});
復制代碼 刪除 index.html 中手動引入的 script 標簽 <!DOCTYPE html>
<html lang=
"en" >
<head><meta charset=
"UTF-8" ><title>從零開始搭建react工程</title>
</head>
<body><div id=
"root" ></div>
</body>
</html>
復制代碼 重新編譯查看 npm run build 瀏覽器打開查看目錄 dist 下的 index.html 以上步驟都成功的前提下繼續走下一步 生成的文件名添加Hash值,目的是解決緩存問題 修改webpack.prod.conf.js,mode: 'production', 增加以下代碼 // webpack.prod.conf.js
output: {filename:
"js/[name].[chunkhash:16].js" ,
},
復制代碼 生成前需要清理之前項目生成的文件,因為由于文件名的改變如果不刪除會一直增加 安裝插件 clean-webpack-plugin $ npm install --save-dev clean-webpack-plugin
復制代碼 // webpack.prod.conf.js
const merge = require(
'webpack-merge' );
const baseWebpackConfig = require(
'./webpack.base.conf.js' );
const HtmlWebpackPlugin = require(
'html-webpack-plugin' );
const CleanWebpackPlugin = require(
'clean-webpack-plugin' );module.exports = merge(baseWebpackConfig, {mode:
'production' ,output: {filename:
"js/[name].[chunkhash:16].js" ,},plugins: [new HtmlWebpackPlugin({template:
'public/index.html' ,inject:
'body' ,minify: {removeComments:
true ,collapseWhitespace:
true ,removeAttributeQuotes:
true },}),new CleanWebpackPlugin([
'../dist' ], { allowExternal:
true })]
});
復制代碼 公共代碼與業務代碼分離 修改 webpack.base.conf.js 的 entry 入口屬性,抽出框架代碼 entry: {app:
'./app/index.js' ,framework: [
'react' ,
'react-dom' ],
},
復制代碼 修改webpack.prod.conf.js,增加以下代碼,目的是分離框架代碼和業務代碼 雖然上面步驟抽出框架代碼生成兩個文件,但是app.js還是包含框架代碼 optimization: {splitChunks: {chunks:
"all" ,minChunks: 1,minSize: 0,cacheGroups: {framework: {
test :
"framework" ,name:
"framework" ,enforce:
true }}}}
復制代碼 cacheGroups對象,定義了需要被抽離的模塊 其中test屬性是比較關鍵的一個值,他可以是一個字符串,也可以是正則表達式,還可以是函數。如果定義的是字符串,會匹配入口模塊名稱,會從其他模塊中把包含這個模塊的抽離出來 name是抽離后生成的名字,和入口文件模塊名稱相同,這樣抽離出來的新生成的framework模塊會覆蓋被抽離的framework模塊 整合 webpack-dev-server $ npm install --save-dev webpack-dev-server
復制代碼 在build中添加webpack.dev.conf.js文件 const path = require(
'path' );
const merge = require(
'webpack-merge' );
const baseWebpackConfig = require(
'./webpack.base.conf.js' );
const HtmlWebpackPlugin = require(
'html-webpack-plugin' );
const webpack = require(
'webpack' );module.exports = merge(baseWebpackConfig, {mode:
'development' ,output: {filename:
"js/[name].[hash:16].js" ,},plugins: [new HtmlWebpackPlugin({template:
'public/index.html' ,inject:
'body' ,minify: {html5:
true },
hash :
false }),new webpack.HotModuleReplacementPlugin()],devServer: {port:
'8080' ,contentBase: path.join(__dirname,
'../public' ),compress:
true ,
history ApiFallback:
true ,hot:
true ,https:
false ,noInfo:
true ,open:
true ,proxy: {}}
});
復制代碼 在package.json scripts屬性添加內容 "dev" :
"webpack-dev-server --inline --progress --config build/webpack.dev.conf.js" ,
復制代碼 npm run dev 自動打開瀏覽器打開入口頁面實時更新 獨立導出 css 文件 $ npm install extract-text-webpack-plugin
$ npm install style-loader css-loader postcss-loader autoprefixer --save-dev
$ npm install less sass less-loader sass-loader stylus-loader node-sass --save-dev
復制代碼 webpack.base.conf.js 文件修改 // webpack.base.conf.js
{
test : /\.css$/,use: [{loader:
"style-loader" //在html中插入<style>標簽},{loader:
"css-loader" ,//獲取引用資源,如@import,url()},{loader:
"postcss-loader" ,options: {plugins:[require(
'autoprefixer' )({browsers:[
'last 5 version' ]})]}}]
},
{
test :/\.less$/,use: [{ loader:
"style-loader" },{ loader:
"css-loader" },{loader:
"postcss-loader" ,//自動加前綴options: {plugins:[require(
'autoprefixer' )({browsers:[
'last 5 version' ]})]}},{ loader:
"less-loader" }]
},
{
test :/\.scss$/,use:[{ loader:
"style-loader" },{loader:
"css-loader" ,},{ loader:
"sass-loader" },{loader:
"postcss-loader" ,options: {plugins:[require(
'autoprefixer' )({browsers:[
'last 5 version' ]})]}}]
},
復制代碼 $ npm i file-loader url-loader --save-dev
復制代碼 webpack.base.conf.js 文件修改 // webpack.base.conf.js
{
test : /\.(png|jpg|gif|woff|svg|eot|woff2|tff)$/,use:
'url-loader?limit=8129' , //注意后面那個
limit 的參數,當你圖片大小小于這個限制的時候,會自動啟用base64編碼圖片exclude: /node_modules/
}
復制代碼 build 時報錯 Error: Chunk.entrypoints: Use Chunks.groupsIterable and filter by instanceof Entrypoint insteadat Chunk.get (F:\react\createApp\node_modules\webpack\lib\Chunk.js:824:9)
復制代碼 webpack4.0中使用“extract-text-webpack-plugin”報錯 解決辦法 $ npm install extract-text-webpack-plugin@next
復制代碼 背景圖片路徑問題 由于css文件分離出來的原因,會導致在css文件夾下找images文件夾下的圖片 解決辦法 publicPath屬性改為 '/',以絕對路徑的方式尋找資源 {
test :/\.(png|jpg|gif)$/,use:[{loader:
'url-loader' ,options: {// outputPath:
'../' ,//輸出**文件夾publicPath:
'/' ,name:
"images/[name].[ext]" ,
limit :500 //是把小于500B的文件打成Base64的格式,寫入JS}}]
},
復制代碼
總結
以上是生活随笔 為你收集整理的基于webpack4.X从零搭建React脚手架 的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔 網站內容還不錯,歡迎將生活随笔 推薦給好友。