基于webpack4.X從零搭建React腳手架的方法步驟
項(xiàng)目初始化
$ npm init
安裝webpack
本次創(chuàng)建是基于webpack4
$ npm install --save-dev
新建webpack配置文件
在根目錄創(chuàng)建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基礎(chǔ)配置和不同環(huán)境的配置
先安裝webpack-merge:
$ 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' });
在根目錄下創(chuàng)建app目錄,然后創(chuàng)建index.js文件
var element =document.getElementById('root'); element.innerHTML = 'hello, world!';
在根目錄創(chuàng)建一個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>
當(dāng)前項(xiàng)目目錄樹
|- /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,已經(jīng)將webpack命令工具遷移到webpack-cli模塊了,需要安裝 webpack-cli
$ npm install --save-dev webpack-cli
package.json文件 scripts屬性配置一個build命令
其值為:webpack --config build/webpack.prod.conf.js,以下是scripts的相關(guān)代碼
// 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
修改app目錄下的index.js的代碼
import React from "react"; import ReactDom from "react-dom"; ReactDom.render( <h1>hello, world!</h1>, document.getElementById("root") );
注意 import 屬于ES6規(guī)范,因此需要轉(zhuǎn)譯ES2015+的語法,安裝并配置 babel 以及相關(guān)依賴
$ npm install --save-dev babel-loader babel-core babel-preset-env babel-preset-react
根目錄創(chuàng)建.babelrc文件,配置presets.
{ "presets": [ [ "env", { "targets": { "browsers": [ "> 1%", "last 5 versions", "ie >= 8" ] } } ], "react" ] }
修改webpack.base.conf.js文件
// 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 } ] } };
運(yùn)行 npm run build
添加插件
public下的index.html本該自動添加到dist目錄,并且引用資源自動加載到該文件,通過html-webpack-plugin實(shí)現(xiàn)這一步
$ 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 標(biāo)簽
<!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
以上步驟都成功的前提下繼續(xù)走下一步
生成的文件名添加Hash值,目的是解決緩存問題
修改webpack.prod.conf.js,mode: 'production', 增加以下代碼
// webpack.prod.conf.js output: { filename: "js/[name].[chunkhash:16].js", },
生成前需要清理之前項(xiàng)目生成的文件,因?yàn)橛捎谖募母淖內(nèi)绻粍h除會一直增加
安裝插件 clean-webpack-plugin
$ npm install --save-dev clean-webpack-plugin
修改 webpack.prod.conf.js
// 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 }) ] });
公共代碼與業(yè)務(wù)代碼分離
修改 webpack.base.conf.js 的 entry 入口屬性,抽出框架代碼
entry: { app: './app/index.js', framework: ['react','react-dom'], },
修改webpack.prod.conf.js,增加以下代碼,目的是分離框架代碼和業(yè)務(wù)代碼
雖然上面步驟抽出框架代碼生成兩個文件,但是app.js還是包含框架代碼
optimization: { splitChunks: { chunks: "all", minChunks: 1, minSize: 0, cacheGroups: { framework: { test: "framework", name: "framework", enforce: true } } } }
cacheGroups對象,定義了需要被抽離的模塊
其中test屬性是比較關(guān)鍵的一個值,他可以是一個字符串,也可以是正則表達(dá)式,還可以是函數(shù)。如果定義的是字符串,會匹配入口模塊名稱,會從其他模塊中把包含這個模塊的抽離出來
name是抽離后生成的名字,和入口文件模塊名稱相同,這樣抽離出來的新生成的framework模塊會覆蓋被抽離的framework模塊
整合 webpack-dev-server
開發(fā)環(huán)境開啟服務(wù)監(jiān)聽文件改動實(shí)時更新最新內(nèi)容
$ 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, historyApiFallback: true, hot: true, https: false, noInfo: true, open: true, proxy: {} } });
在package.json scripts屬性添加內(nèi)容
"dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js",
npm run dev
自動打開瀏覽器打開入口頁面實(shí)時更新
獨(dú)立導(dǎo)出 css 文件
安裝css相關(guān)依賴
sass less 預(yù)處理
$ 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>標(biāo)簽 }, { 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的參數(shù),當(dāng)你圖片大小小于這個限制的時候,會自動啟用base64編碼圖片 exclude: /node_modules/ }
build 時報錯
Error: Chunk.entrypoints: Use Chunks.groupsIterable and filter by instanceof Entrypoint instead
at 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文件分離出來的原因,會導(dǎo)致在css文件夾下找images文件夾下的圖片
解決辦法 publicPath屬性改為 '/',以絕對路徑的方式尋找資源
{ test:/\.(png|jpg|gif)$/, use:[{ loader:'url-loader', options: { // outputPath:'../',//輸出**文件夾 publicPath: '/', name: "images/[name].[ext]", limit:500 //是把小于500B的文件打成Base64的格式,寫入JS } }] },
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
react-beautiful-dnd拖拽排序功能的實(shí)現(xiàn)過程
這篇文章主要介紹了react-beautiful-dnd拖拽排序功能的實(shí)現(xiàn)過程,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-07-07React中setState/useState的使用方法詳細(xì)介紹
這篇文章主要介紹了React中setState/useState的使用方法,useState 和 setState 在React開發(fā)過程中 使用很頻繁,但很多人都停留在簡單的使用階段,并沒有正在了解它們的執(zhí)行機(jī)制2023-04-04react-routerV6版本和V5版本的詳細(xì)對比
React-Router5是React-Router6的前一個版本,它已經(jīng)被React-Router6取代,React-Router 6是一次較大的重大更新,本文就來介紹一下react-routerV6版本和V5版本的詳細(xì)對比,感興趣的可以了解一下2023-12-12react如何使用mobx6動態(tài)加載數(shù)據(jù)
MobX是一個強(qiáng)大而簡單的狀態(tài)管理工具,它可以幫助我們更好地組織和管理React應(yīng)用程序中的數(shù)據(jù)流,本文給大家介紹react如何使用mobx6動態(tài)加載數(shù)據(jù),感興趣的朋友跟隨小編一起看看吧2024-02-02react 組件表格固定底部的實(shí)現(xiàn)代碼
在React中,要實(shí)現(xiàn)一個組件表格并且固定底部,可以使用CSS的固定定位或絕對定位來實(shí)現(xiàn),下面通過示例代碼給大家分享react 組件表格固定底部的實(shí)現(xiàn)代碼,感興趣的朋友跟隨小編一起看看吧2024-05-05使用React實(shí)現(xiàn)一個簡單的待辦事項(xiàng)列表的示例代碼
這篇文章我們將詳細(xì)講解如何建立一個這樣簡單的列表,文章通過代碼示例介紹的非常詳細(xì),對我們的學(xué)習(xí)或工作有一定的幫助,需要的朋友可以參考下2023-08-08