目錄介紹
src:里面的每個文件夾就是一個頁面,頁面開發相關的組件、圖片和樣式文件就存放在對應的文件夾下。
tpl:里面放置模板文件,當webpack打包時為html-webpack-plugin插件提供模板。
tsconfig.json:typescript的配置文件,需要自己新建並編寫。
webpack.config.js:webpack的配置文件,需要自己新建並編寫。
config:文件夾下的index.dev.js用來配置開發模塊,index.js配置發布模塊。將會在webpack.config.js中引用。index.dev.js是index.js的子集,index.js包含了所有的頁面。
index.dev.js
module.exports = { page2: { title: "hello world!", tpl: "index" } };
index.js
module.exports = { page1: { title: "hello world!", tpl: "index" }, page2: { title: "hello world!", tpl: "index" } };
npm初始化項目
執行npm init命令,填寫完基本信息后會生成一個package.json文件,"dependencies"屬性是在安裝依賴包附帶--save參數時生成的,“devDependencies”屬性是在安裝開發依賴包附帶--save-dev參數時生成的。
npm init
package.json文件
{ "name": "react-demo", "version": "1.0.0", "description": "react+typescript+webpack項目", "private": true, //設置為true,那么npm將拒絕發布它,防止私人存儲庫意外發布 "scripts": { // 自定義腳本,通過npm run執行腳本 "start": "webpack-dev-server --mode development --cfg dev", //啟動web服務器,cfg是自定義參數,賦值為dev。 "build": "webpack --mode production" }, "keywords": [ "react", "typescript", "webpack" ], "author": "chencong", "license": "ISC", "devDependencies": { "clean-webpack-plugin": "^1.0.1", "html-webpack-plugin": "^3.2.0", "ts-loader": "^5.3.3", "typescript": "^3.3.3", "webpack": "^4.29.3", "webpack-cli": "^3.2.3", "webpack-dev-server": "^3.1.14", "yargs": "^13.1.0" }, "dependencies": { "react": "^16.8.2", "react-dom": "^16.8.2" } }
添加react
npm install --save react react-dom
添加typescript
安裝typescript編譯器和loader
npm install --save-dev typescript ts-loader
安裝完成后需要編寫配置文件,在項目中新建tsconfig.json文件。配置完后就該ts-loader登場了,在webpack.config.js中配置loader,將項目中所有的用typescript語法編寫的文件都用ts-loader處理,處理的依據就是tsconfig.json文件。還有一點需要提一下,項目可以不用babel進行轉碼了,因為ts-loader已經幫我們處理了,tsconfig.json中“target”: “es5”就是轉碼成es5的配置,"jsx": "react"就是對jsx的支持,不需要用babel-preset-react進行轉碼。(typescript配置文檔)
{ "version": "1.0.0", "compilerOptions": { "baseUrl": "./", //解析非相對模塊的基准目錄 "paths": { //路徑映射,如在文件中使用‘~/’相當於‘src/’ "~/*": ["src/*"] }, "module": "esnext", //指定生成哪個模塊系統的代碼 "target": "es5", //生成es5的js文件 "jsx": "react", //在tsx文件里支持jsx "sourceMap": true, "moduleResolution": "node", //決定如何處理模塊 "allowJs": true, //允許編譯js文件 "strictNullChecks": false, //在嚴格的 null檢查模式下, null和 undefined值不包含在任何類型里,只允許用它們自己和 any來賦值(有個例外, undefined可以賦值到 void) "lib": ["es2015", "dom", "es2015.promise"] //編譯過程中需要引入的庫文件的列表 }, "include": ["src/**/*"], //編譯包含在 src及其子目錄下的所有匹配的文件 "exclude": ["dist", "node_modules"] //編譯時排除 dist、node_modules文件夾 }
添加webpack
執行以下命令添加webpack,使用webpack 4.X的命令行需要單獨安裝命令行工具,所以也要安裝webpack-cli。html-webpack-plugin插件幫助我們在打包時根據模板生成html文件,還需注意模板中title標簽的寫法,應為<title><%= htmlWebpackPlugin.options.title%></title>。clean-webpack-plugin插件會在項目打包前刪除指定的文件,通常用來刪除舊的打包文件。yargs包提供了獲取命令行中參數的對象。
npm install --save-dev webpack webpack-cli html-webpack-plugin clean-webpack-plugin yargs
接下來編寫webpack的配置文件,在項目中新建配置文件webpack.config.js。(webpack文檔)
const path = require("path"); const argv = require("yargs").argv; //獲取命令行中參數的對象 const HtmlWebpackPlugin = require("html-webpack-plugin"); const CleanPlugin = require("clean-webpack-plugin"); const webpack = require("webpack"); const isDev = argv.cfg && argv.cfg === "dev"; //是否為開發模式,如果輸入yarn start執行"webpack-dev-server --mode development --cfg dev",argv.cfg獲取參數的值為dev。 let compileConfig = "index"; if (isDev) { compileConfig = "index." + argv.cfg; } const buildConfig = require(`./config/${compileConfig}`); // 開發模式下,引入index.dev.js中的配置信息。生產模式下,引入index.js中的配置信息 const modules = Object.keys(buildConfig); const entry = Object.create(null); const htmlPlugins = []; if (modules.length > 0) { for (let srcModule of modules) { entry[srcModule] = path.resolve(__dirname, `./src/${srcModule}`); // 多頁面應用webpack配置文件entry屬性的值 htmlPlugins.push( // html-webpack-plugin插件生成html的配置 new HtmlWebpackPlugin({ title: buildConfig[srcModule]["title"], filename: `${srcModule}/index.html`, template: path.resolve(__dirname, "./tpl/index.html"), chunks: [srcModule] }) ); } } const config = { entry, output: { publicPath: "/dist/", filename: "[name].[hash].js", path: path.resolve(__dirname, "dist") },
module: {
rules: [
{ // 除了node_modules文件夾中的文件,所有的tsx文件都用ts-loader處理
test: /\.tsx?$/,
use: "ts-loader",
exclude: /node_modules/
}
]
} plugins: [new CleanPlugin(['dist']), ...htmlPlugins], resolve: { extensions: [".tsx", ".ts", ".js"] }, devtool: isDev ? "source-map" : false // 值為source-map時,方便在瀏覽器中使用react開發工具調試 }; if (isDev) { // 開發模式時,啟動web服務 config.devServer = {
contentBase: './dist', // 告訴服務器那個文件夾提供靜態資源 port: 9000, open: true, hot: false, // 啟用webpack中的熱替換特性,這里我們不用熱替換(不刷新整個頁面的情況下更新部分更改)而用熱更新(整個頁面自動刷新) openPage: `dist/${modules[0]}` // 打開index.dev.js配置中的第一個頁面 }; // config.plugins.push(new webpack.HotModuleReplacementPlugin()); // 熱替換需要的插件 } module.exports = config;
關於樣式
webpack在打包除javascript以外的靜態資源時,需要用loader預處理。在實際開發中我通常用less來寫樣式,所以先要用less將less文件編譯成css ,然后用css-loader預處理css文件。最后還需要用mini-css-extract-plugin插件將css從webpack打包后的文件中抽離出來按需加載,或者用style-loader將css以內聯的方式加載,mini-css-extract-plugin插件和style-loader不能同時使用,推薦使用前者將樣式抽離出來按需加載。
安裝
npm install --save-dev css-loader less-loader less mini-css-extract-plugin
webpack.config.js中配置
module: { rules: [ ... { test: /\.less$/, use: [ // webpack會從右往左加載loader,所有書寫loader時有順序要求 // {
// loader: 'style-loader' //style-loader不能和mini-css-extract-plugin同時使用
// } MiniCssExtractPlugin.loader, {
loader: 'css-loader'
}, {
loader: 'less-loader'
} ] } ... ] }, plugins: [ ... new MiniCssExtractPlugin({ filename: "[name].[hash].css", chunkFilename: "[name].[hash].css" }), ... ],
autoprefixer
寫樣式時為了兼容不同的瀏覽器,css3的特性需要加前綴,例如:
-moz- 對應 Firefox, -webkit- 對應 Safari and Chrome -o- 對應 Opera -ms- 對應 Internet Explorer
如果自己手動地寫就會很麻煩,於是就有了autoprofixer幫我們自動添加這些前綴。postcss-flexbugs-fixe是用來修復一些flexbox的bug。
安裝
cnpm install --save-dev postcss-loader autoprefixer postcss-flexbugs-fixes
webpack.config.js中配置
module: { rules: [ ... { test: /\.less$/, use: [ // { // loader: "style-loader" // }, MiniCssExtractPlugin.loader, { loader: "css-loader" }, { loader: "less-loader" }, { loader: "postcss-loader", options: { ident: "postcss", // postcss-loader中options里使用了function、require時需要ident屬性,可以是任意值 plugins: () => [ require("postcss-flexbugs-fixes"), autoprefixer({ browsers: [ ">1%", "last 4 versions", "Firefox ESR", "not ie < 9" ], flexbox: "no-2009" // false將禁用flexbox屬性前綴。或flexbox:“no-2009”將僅為最終版本和IE版本的規范添加前綴。 }) ] } }, ] } ] },
圖片處理
頁面引入圖片如:background: url(,/images/logo.png) ,webpack打包時無法解析圖片報錯,這時就需要loader來處理圖片。
ur-loader可以將圖片轉化成base64的格式,以減少請求次數。。
安裝
npm i -D url-loader
webpack.config.js配置
module: { rules: [ ... { test: /\.png|jpg|gif|jpeg|svg/, use: [ { loader: 'url-loader', options: { limit: 10000, // 當圖片小於limit(單位:byte)時圖片轉換成base64,大於limit時其表現行為等於file-loader name: './images/[name].[hash:8].[ext]' // 當圖片大於limit時起作用 ,'./images'表示圖片打包的路徑相對於output.path,[name]表示圖片的名稱,[hash:8]表示9位數的hash值,[ext]表示保持原來的后綴名
} } ] } ] }
以上就是構建多頁面應用的所有配置了,如有疑問或有更好的建議歡迎交流!