React+TypeScript+webpack4多入口配置詳解
資源
- React-16.8.*
- react-router-dom-4.3.*
- TypeScript-3.5.*
- webpack-4.*
- eslint-5.16.*
項(xiàng)目目錄
├── dist # 打包結(jié)果目錄 │ ├── demo1 //類別demo1的打包結(jié)果 │ │ ├── demo1.himl │ │ ├── demo1.js │ │ └── demo1.css │ └── demo2 ... //類別demo2的打包結(jié)果 ├── src # 業(yè)務(wù)資源文件目錄 │ ├── category //項(xiàng)目分類 │ │ ├── demo1 │ │ ├── demo2 │ │ └── ... │ ├── components //公共組件 │ ├── util //公共資源 │ └── custom.d.ts //項(xiàng)目全局變量聲明文件 ├── index.html //項(xiàng)目啟動(dòng)入口 ├── .gitignore //git忽略文件 ├── .eslintrc.js //eslint校驗(yàn)配置 ├── package.json //依賴包 ├── tsconfig.json //ts配置 ├── webpack.config.build.js //webpack打包 ├── webpack.config.base.js //webpack基礎(chǔ)配置 └── webpack.config.js //項(xiàng)目啟動(dòng)配置
前言
對(duì)于復(fù)雜或多人開發(fā)的 React 項(xiàng)目來說,管理和使用每個(gè)組件的 props 、 state 或許會(huì)成為一件讓人頭痛的事情,而為每一個(gè)組件寫文檔,成本也會(huì)比較大,對(duì)項(xiàng)目的開發(fā)效率也不是最理想的。
Typescript 給 React 帶來很多好處:
- 在組件頭部定義 interface,讓每個(gè)人在拿到組件的第一時(shí)間就可以很明確知道該組件需要使用的 props 和 state;
- 在編譯中發(fā)現(xiàn)問題,減少運(yùn)行時(shí)的報(bào)錯(cuò);
- 可以在編輯器中實(shí)現(xiàn)實(shí)時(shí)類型校驗(yàn)、引用查詢;
- 約束類型,在混合多語言環(huán)境中降低風(fēng)險(xiǎn),等。
需求
要搭建一個(gè)React+TypeScript+webpack的項(xiàng)目的話,一般都是團(tuán)隊(duì)開發(fā)多人多文件項(xiàng)目,在搭建之前需要優(yōu)先考慮以下幾個(gè)方面:
- 開發(fā)體驗(yàn)
- 項(xiàng)目打包
- 團(tuán)隊(duì)規(guī)范
安裝
前置安裝
首先需要全局安裝typescript,這里默認(rèn)大家都已經(jīng)安裝了node以及npm
npm install -g typescript
首先新建文件夾并進(jìn)入
mkdir tsDemo && cd tsDemo
然后進(jìn)行初始化,生成package.json和tsconfig.json
npm init -y && tsc --init
安裝開發(fā)工具
npm install-D webpack webpack-cli webpack-dev-server
安裝react相關(guān)
因?yàn)樾枰蟭s,而react原本的包是不包含驗(yàn)證包的,所以這里也需要安裝相關(guān)ts驗(yàn)證包
npm install -S react react-dom npm install -D @types/react @types/react-dom
安裝ts-loader
npm install -D ts-loader
以上是基本的 后續(xù)會(huì)貼出項(xiàng)目demo里面包含所有依賴包
webpack配置
添加webpack文件
根目錄下新建webpack.config.base.js、webpack.config.build.js、webpack.config.js文件
touch webpack.config.base.js webpack.config.build.js webpack.config.js
- entry:入口文件(你要打包,就告訴我打包哪些)
- output:出口文件(我打包完了,給你放到哪里)
- resolve: 尋找模塊所對(duì)應(yīng)的文件
- module:模塊(放lorder,編譯瀏覽器不認(rèn)識(shí)的東西)
- plugins:插件(輔助開發(fā),提高開發(fā)效率)
- externals:打包忽略
- devServer:服務(wù)器(webpack提供的本地服務(wù)器)
- mode:模式,分為開發(fā)模式、生產(chǎn)模式。此為4.X里新增的
配置entry入口文件
因?yàn)榇蟛糠猪?xiàng)目是多入口,多類別的,所有入口配置時(shí)不要配置單一入口
const fs = require("fs"); const path = require("path"); const optimist = require("optimist"); const cateName = optimist.argv.cate; let entryObj = {}; const srcPath = `${__dirname}/src`; //獲取當(dāng)前項(xiàng)目要啟動(dòng)或者打包的基礎(chǔ)路徑 const entryPath = `${srcPath}/category/`; //未指定類別 啟動(dòng)或者打包所有類別 //如:npm run dev 或者npm run build if (cateName == true) { fs.readdirSync(entryPath).forEach((cateName, index) => { // cateName/cateName指定輸出路徑為entryname if (cateName != "index.html" && cateName != ".DS_Store") entryObj[`${cateName}/${cateName}`] = `${entryPath + cateName}/${cateName}.tsx`; }); } else if (cateName.indexOf(",")) { // 一次指定多個(gè)類別 類別之間以","分割 //如:npm run dev erhsouche,huoche let cateNameArray = cateName.split(","); for (let i = 0; i < cateNameArray.length; i++) { entryObj[`${cateNameArray[i]}/${cateNameArray[i]}`] = `${entryPath + cateNameArray[i]}/${ cateNameArray[i] }.tsx`; } } else { // 打包單個(gè)入口文件 //如:npm run dev ershouche entryObj[`${cateName}/${cateName}`] = `${entryPath + cateName}/${cateName}.tsx`; } const webpackConfig = { entry: entryObj, } module.exports = { webpackConfig, entryObj };
配置output出口文件
const webpackConfig = { output: { //輸出文件名稱以當(dāng)前傳入的cate類別名稱命名 filename: "[name].js", //輸出到根目錄下的dist目錄中 path: path.resolve(__dirname, "dist"), publicPath: "/", }, }
配置resolve
需要import xxx from 'xxx'這樣的文件的話需要在webpack中的resolve項(xiàng)中配置extensions,這樣以后引入文件就不需要帶擴(kuò)展名
const webpackConfig = { resolve: { extensions: [".tsx", ".ts", ".js", ".jsx", ".json"], //配置項(xiàng)通過別名來把原導(dǎo)入路徑映射成一個(gè)新的導(dǎo)入路徑。 alias: { images: path.join(__dirname, "src/util/img") }, // 使用絕對(duì)路徑指明第三方模塊存放的位置,以減少搜索步驟 modules: [path.resolve(__dirname, "node_modules")] }, }
配置module
概念
在webpack中任何一個(gè)東西都稱為模塊,js就不用說了。一個(gè)css文件,一張圖片、一個(gè)less文件都是一個(gè)模塊,都能用導(dǎo)入模塊的語法(commonjs的require,ES6的import)導(dǎo)入進(jìn)來。webpack自身只能讀懂js類型的文件,其它的都不認(rèn)識(shí)。但是webpack卻能編譯打包其它類型的文件,像ES6、JSX、less、typeScript等,甚至css、images也是Ok的,而想要編譯打包這些文件就需要借助loader
loader就像是一個(gè)翻譯員,瀏覽器不是不認(rèn)識(shí)這些東西么?那好交給loader來辦,它能把這些東西都翻譯成瀏覽器認(rèn)識(shí)的語言。loader描述了webpack如何處理非js模塊,而這些模塊想要打包loader必不可少,所以它在webpack里顯得異常重要。loader跟插件一樣都是模塊,想要用它需要先安裝它,使用的時(shí)候把它放在module.rules參數(shù)里,rules翻譯過來的意思就是規(guī)則,所以也可以認(rèn)為loader就是一個(gè)用來處理不同文件的規(guī)則
所需loader
ts-loader
編譯TypeScript文件
npm install ts-loader -D
url-loader
處理css中的圖片資源時(shí),我們常用的兩種loader是file-loader或者url-loader,兩者的主要差異在于。url-loader可以設(shè)置圖片大小限制,當(dāng)圖片超過限制時(shí),其表現(xiàn)行為等同于file-loader,而當(dāng)圖片不超過限制時(shí),則會(huì)將圖片以base64的形式打包進(jìn)css文件,以減少請(qǐng)求次數(shù)。
npm install url-loader -D
css處理所需loader
css-loader 處理css
sass-loader 編譯處理scss
sass-resources-loader 全局注冊(cè)變量
html-loader
處理.html文件
module完整配置
const webpackConfig = { module: { rules: [ //處理tsx文件 { test: /\.(tsx|ts)?$/, use: ["ts-loader"], include: path.resolve(__dirname, "src") }, //處理圖片資源 { test: /\.(png|jpe?g|jpg|gif|woff|eot|ttf|svg)/, use: [ // 對(duì)非文本文件采用file-loader加載 { loader: "url-loader", options: { limit: 1024 * 30, // 30KB以下的文件 name: "images/[name].[hash:8].[ext]", } } ], }, //處理css和scss { test: /\.(css|scss)$/, use: [ //css單獨(dú)打包 MiniCssExtractPlugin.loader, { loader: "css-loader" }, { loader: "postcss-loader", options: { plugins: () => [require("autoprefixer")], sourceMap: true } }, { loader: "sass-loader", options: { sourceMap: true } }, { loader: "sass-resources-loader", options: { resources: ["./skin/mixin.scss", "./skin/base.scss"] } } ], exclude: path.resolve(__dirname, "node_modules") }, { test: /\.html$/, use: { loader: "html-loader", } }, { test: /src\/containers(\/.*).(tsx|ts)/, loader: "bundle-loader?lazy!ts-loader" }, { enforce: "pre", test: /\.js$/, loader: "source-map-loader" } ] }, }
配置plugins
plugins里面放的是插件,插件的作用在于提高開發(fā)效率,能夠解放雙手,讓我們?nèi)プ龈嘤幸饬x的事情。一些很low的事就統(tǒng)統(tǒng)交給插件去完成。
const webpackConfig = { plugins: [ //清除文件 new CleanWebpackPlugin(), //css單獨(dú)打包 new MiniCssExtractPlugin({ filename: "[name].css", chunkFilename: "[name].css" }), // 引入熱更新插件 new webpack.HotModuleReplacementPlugin() ] }
配置externals
如果需要引用一個(gè)庫,但是又不想讓webpack打包(減少打包的時(shí)間),并且又不影響我們?cè)诔绦蛑幸訡MD、AMD或者window/global全局等方式進(jìn)行使用(一般都以import方式引用使用),那就可以通過配置externals。
const webpackConfig = { //項(xiàng)目編譯打包是忽略這些依賴包 externals: { react: "React", "react-dom": "ReactDOM", "react-redux": "ReactRedux", } }
配置mode
mode是webpack4新增的一條屬性,它的意思為當(dāng)前開發(fā)的環(huán)境。mode的到來減少了很多的配置,它內(nèi)置了很多的功能。相較以前的版本提升了很多,減少了很多專門的配置
- 提升了構(gòu)建速度
- 默認(rèn)為開發(fā)環(huán)境,不需要專門配置
- 提供壓縮功能,不需要借助插件
- 提供SouceMap,不需要專門配置
mode分為兩種環(huán)境,一種是開發(fā)環(huán)境(development),一種是生產(chǎn)環(huán)境(production)。開發(fā)環(huán)境就是我們寫代碼的環(huán)境,生產(chǎn)環(huán)境就是代碼放到線上的環(huán)境。這兩種環(huán)境的最直觀區(qū)別就是,開發(fā)環(huán)境的代碼不提供壓縮,生產(chǎn)環(huán)境的代碼提供壓縮。
配置devServer
const webpackConfig = { devServer: { // 本地服務(wù)器所加載的頁面所在的目錄 contentBase: srcPath, //熱更新 hot: true, //服務(wù)端口 port: "7788", // 是否向Chunk中注入代理客戶端,默認(rèn)注入 inline: true, // publicPath: '/dist/', historyApiFallback: { index: "template.html", }, //默認(rèn)檢查hostname disableHostCheck: true, compress: true, open: true // 自動(dòng)打開首頁 } }
以上就是本文的全部內(nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
React特征Form?單向數(shù)據(jù)流示例詳解
這篇文章主要為大家介紹了React特征Form?單向數(shù)據(jù)流示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-09-09詳解react的兩種動(dòng)態(tài)改變css樣式的方法
這篇文章主要介紹了詳解react的兩種動(dòng)態(tài)改變css樣式的方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-04-04基于React的狀態(tài)管理實(shí)現(xiàn)一個(gè)簡單的顏色轉(zhuǎn)換器
這篇文章主要介紹了用React的狀態(tài)管理,簡簡單單實(shí)現(xiàn)一個(gè)顏色轉(zhuǎn)換器,文中有詳細(xì)的代碼示例供大家參考,具有一定的參考價(jià)值,需要的朋友可以參考下2023-08-08淺談redux以及react-redux簡單實(shí)現(xiàn)
這篇文章主要介紹了淺談redux以及react-redux簡單實(shí)現(xiàn),小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-08-08react-beautiful-dnd拖拽排序功能的實(shí)現(xiàn)過程
這篇文章主要介紹了react-beautiful-dnd拖拽排序功能的實(shí)現(xiàn)過程,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-07-07