摘要:最近有一個(gè)項(xiàng)目,考慮到要進(jìn)行,所以要做成多頁(yè)面應(yīng)用。為了保證開發(fā)速度和開發(fā)效率,所以決定使用做一套模塊化配置方案。
目錄最近有一個(gè)項(xiàng)目,考慮到要進(jìn)行 SEO,所以要做成多頁(yè)面應(yīng)用。為了保證開發(fā)速度和開發(fā)效率,所以決定使用 webpack 做一套模塊化配置方案。
下面主要針對(duì)一些重要的點(diǎn)提供思路,并不作詳解。完整的代碼,我會(huì)放在 github(項(xiàng)目地址)上供大家參考,如果有優(yōu)化的地方,請(qǐng)?jiān)谠u(píng)論區(qū)指點(diǎn)出來,。
|-- build webpack 配置 | |-- utils.js 處理 webpack 配置的公共方法 | |-- webpack.base.conf.js 公共配置 | |-- webpack.dev.conf.js 開發(fā)環(huán)境配置 | |-- webapck.prod.conf.js 生產(chǎn)環(huán)境配置 | |-- webpack.rules.conf.js 文件處理規(guī)則 |-- dist 存放變異后文件 |-- | |-- src 源文件 | |-- assets | |-- pages | | |-- index 首頁(yè) | | | |-- index.html 首頁(yè)模板 | | | |-- index.js 首頁(yè)入口文件 | htmlarrary.js 頁(yè)面配置文件多頁(yè)面
多頁(yè)面,首先最重要的就是處理多個(gè) html 模板和對(duì)應(yīng)的多個(gè)入口文件。
html 模板在項(xiàng)目根目錄創(chuàng)建一個(gè) htmlarrary.js,用來存儲(chǔ)頁(yè)面配置:
// htmlarrary.js module.exports = [ { _html: "index", title: "首頁(yè)", chunks: ["index", "manifest", "vendors"] // 頁(yè)面用到的vendor模塊 }, { _html: "login", title: "登錄", chunks: ["login"] } ]
然后在 /build/utils.js 創(chuàng)建 getHtmlArray 方法,用來自動(dòng)生成多個(gè)模板的配置:
// /build/utils.js const HtmlWebpackPlugin = require("html-webpack-plugin") const htmlArray = require("../htmlarray.js") exports.getHtmlArray = function (moduleExportsPlugins) { // 根據(jù)模板配置生成 HtmlWebpackPlugin 需要的配置 const getHtmlConfig = function (name, chunks, title) { return { template: `./src/pages/${name}/index.html`, filename: `./${name}.html`, favicon: "./src/assets/images/public/favicon.ico", title, inject: true, hash: true, // 開啟hash chunks, // 頁(yè)面要引入的包 minify: process.env.NODE_ENV === "development" ? false : { removeComments: true, // 移除HTML中的注釋 collapseWhitespace: true, // 折疊空白區(qū)域 也就是壓縮代碼 removeAttributeQuotes: true, // 去除屬性引用 }, }; }; // 循環(huán)創(chuàng)建模板配置 htmlArray.forEach((element) => { const { _html, chunks, title } = element moduleExportsPlugins.push(new HtmlWebpackPlugin(getHtmlConfig(_html, chunks, title))) }) }
在 webpack.base.conf.js 中通過 getHtmlArray 添加多頁(yè)面引擎配置:
const { getHtmlArray } = require("./utils.js") module.exports = { // ... 相關(guān)配置 } getHtmlArray(module.exports.plugins)入口文件
在 /build/utils.js 創(chuàng)建 getEntry 方法,用來自動(dòng)生成入口文件的配置:
// /build/utils.js const glob = require("glob") exports.getEntry = function () { const entry = {} // 讀取src目錄所有page入口 glob.sync("./src/pages/*/*.js").forEach((name) => { const start = name.indexOf("src/") + 4; const end = name.length - 3; const eArr = []; const n = name.slice(start, end).split("/")[1]; eArr.push(name); eArr.push("@babel/polyfill"); // 引入這個(gè),是為了用async await,一些IE不支持的屬性能夠受支持,兼容IE瀏覽器用的 entry[n] = eArr; }) return entry; }
在 webpack.base.conf.js 中通過 getEntry 添加多入口配置:
// webpack.base.conf.js const { getEntry } = require("./utils.js") module.exports = { entry: getEntry(), }JS
JS 方面,我們一般有以下需求:
eslint 錯(cuò)誤提醒;
ts-loader 解析 typescript 語法;
babel-loader 解析 ES6 語法。
針對(duì)以上需求,我們來配置一下子 rules,并且做一下延伸:
// webpack.rules.conf.js module.exports = [ { test: /.(js|ts)$/, exclude: /node_modules/, use: [ { loader: "babel-loader", options: { presets: [ ["@babel/preset-env", { useBuiltIns: "usage", targets: { chrome: "58", ie: "8" }, corejs: 2 }] ] } }, { loader: "ts-loader" }, { loader: "eslint-loader", options: { cache: true // 優(yōu)化打包速度 } } ] } ]
在生產(chǎn)環(huán)境,我們需要對(duì) js 文件進(jìn)行壓縮,公共代碼抽離,所以還需要在 webpack.prod.conf.js 中這樣去優(yōu)化一下:
// webpack.prod.conf.js cconst merge = require("webpack-merge") const UglifyJsPlugin = require("uglifyjs-webpack-plugin") const baseConfig = require("./webpack.base.conf.js") const prodConfig = { optimization: { minimizer: [ // 會(huì)導(dǎo)致 sourcemap 消失 new UglifyJsPlugin({ uglifyOptions: ({ compress: false }) }), new OptimizeCSSAssetsPlugin({}) ], splitChunks: { chunks: "all", cacheGroups: { vendors: { // 抽離第三方插件 test: /[/]node_modules[/]/, // 指定是node_modules下的第三方包 name: "vendors", priority: -10 // 抽取優(yōu)先級(jí) }, utilCommon: { // 抽離自定義 name: "common", minSize: 0, // 將引用模塊分離成新代碼文件的最小體積 minChunks: 2, // 表示將引用模塊如不同文件引用了多少次,才能分離生成新chunk priority: -20 } } }, // optimization.runtimeChunk 就是告訴 webpack 是否要把這部分多帶帶打包出來,來優(yōu)化緩存問題 runtimeChunk: { name: "manifest" } } } module.exports = merge(baseConfig, prodConfig)CSS
CSS 方面,我們一般有以下需求:
postcss-loader 安裝 autoprefixer 插件,自動(dòng)進(jìn)行兼容性處理;
sass-loader 解析 sass 語法;
MiniCssExtractPlugin 進(jìn)行 css 壓縮。
針對(duì)以上需求,我們來配置一下子 rules,并且做一下延伸:
// webpack.rules.conf.js const MiniCssExtractPlugin = require("mini-css-extract-plugin") module.exports = [ { test: /.scss$/i, use: [ Object.assign( // 生產(chǎn)環(huán)境壓縮 css 需要使用 MiniCssExtractPlugin.loader 代替 style-loader { loader: process.env.NODE_ENV === "production" ? MiniCssExtractPlugin.loader : "style-loader" }, // 解決編譯后 css 圖片不能正常顯示的問題 process.env.NODE_ENV === "production" ? { options: { publicPath: "../" } } : {} ), "css-loader", "sass-loader", "postcss-loader" ] } ]
在生產(chǎn)環(huán)境,我們需要對(duì) css 文件進(jìn)行壓縮,所以還需要在 webpack.prod.conf.js 中這樣去優(yōu)化一下:
// webpack.prod.conf.js cconst merge = require("webpack-merge") const MiniCssExtractPlugin = require("mini-css-extract-plugin") const OptimizeCSSAssetsPlugin = require("optimize-css-assets-webpack-plugin") const baseConfig = require("./webpack.base.conf.js") const prodConfig = { optimization: { minimizer: [ new OptimizeCSSAssetsPlugin({}) ], }, plugins: [ new MiniCssExtractPlugin({ filename: "css/[name].[contenthash:8].css", chunkFileName: "[id].[contenthash:8].css" }), ] } module.exports = merge(baseConfig, prodConfig)images
images 方面,我們一般有以下需求:
css 和 js 中的圖片可以被解析;
html 中 img 標(biāo)簽的圖片可以被解析。
針對(duì)以上需求,我們來配置一下子 rules,并且做一下延伸:
// webpack.rules.conf.js const MiniCssExtractPlugin = require("mini-css-extract-plugin") module.exports = [ { test: /.html$/, use: [ // 如果 img 標(biāo)簽的 src 為空的話,就報(bào)錯(cuò) xxxHTMLLINKxxx0. { loader: "html-loader", } ] }, { test: /.(png|jpg|gif|ico)$/, use: [ { loader: "url-loader", options: { name: "[name].[hash:8].[ext]", limit: 30000, outputPath: "./images" } } ] } ]其他 devserver 和 熱更新
// webpack.dev.conf.js const devConfig = { devServer: { open: true, host: "0.0.0.0", port: 2000, useLocalIp: true, hot: true }, plugins: [ new webpack.HotModuleReplacementPlugin() ] }
這樣智能啟動(dòng) css 熱更新,如果需要 js 熱更新,需要添加一段代碼,請(qǐng)自行查找 官網(wǎng)文檔。報(bào)錯(cuò)
如果 img 標(biāo)簽的 src 為空的話,就報(bào)錯(cuò) xxxHTMLLINKxxx0.
如果報(bào)錯(cuò):TS2688: Cannot find type definition file for "unist". 說明需要安裝依賴 @types/unist,其他類似報(bào)錯(cuò)一樣,這是 [email protected] 更換 types 支持方式導(dǎo)致的報(bào)錯(cuò)。
編譯后 css 圖片路徑錯(cuò)誤,根據(jù)是否是生產(chǎn)環(huán)境來動(dòng)態(tài)添加 publicPath,點(diǎn)擊這里。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/104713.html
摘要:最近有一個(gè)項(xiàng)目,考慮到要進(jìn)行,所以要做成多頁(yè)面應(yīng)用。為了保證開發(fā)速度和開發(fā)效率,所以決定使用做一套模塊化配置方案。 最近有一個(gè)項(xiàng)目,考慮到要進(jìn)行 SEO,所以要做成多頁(yè)面應(yīng)用。為了保證開發(fā)速度和開發(fā)效率,所以決定使用 webpack 做一套模塊化配置方案。 下面主要針對(duì)一些重要的點(diǎn)提供思路,并不作詳解。完整的代碼,我會(huì)放在 github(項(xiàng)目地址)上供大家參考,如果有優(yōu)化的地方,請(qǐng)?jiān)?..
摘要:例如允許我們?cè)诖虬鼤r(shí)將腳本分塊利用瀏覽器緩存我們能夠有的放矢的加載資源。文章的內(nèi)容大體分為兩個(gè)方面,一方面在思路制定模塊分離的策略,另一方面從技術(shù)上對(duì)方案進(jìn)行落地。我之前提到測(cè)試之下是什么樣具體的場(chǎng)景并不重要。前言 隨著前端代碼需要處理的業(yè)務(wù)越來越繁重,我們不得不面臨的一個(gè)問題是前端的代碼體積也變得越來越龐大。這造成無論是在調(diào)式還是在上線時(shí)都需要花長(zhǎng)時(shí)間等待編譯完成,并且用戶也不得不花額外的...
摘要:的本質(zhì)是一個(gè),它獨(dú)立于主線程,因此它不能直接訪問,也不能直接訪問對(duì)象,但是,可以訪問對(duì)象,也可以通過消息傳遞的方式與主線程進(jìn)行通信。的最佳用法其實(shí)就是配合做離線緩存。 什么是Service Worker Service Worker本質(zhì)上充當(dāng)Web應(yīng)用程序與瀏覽器之間的代理服務(wù)器,也可以在網(wǎng)絡(luò)可用時(shí)作為瀏覽器和網(wǎng)絡(luò)間的代理。它們旨在(除其他之外)使得能夠創(chuàng)建有效的離線體驗(yàn),攔截網(wǎng)絡(luò)請(qǐng)...
摘要:年前放假的最后一天,我們上線了獨(dú)家記憶活動(dòng)宣傳頁(yè)。微信分享主要代碼參考獨(dú)家記憶當(dāng)時(shí)光凝固,當(dāng)回憶定格。這是屬于我和的獨(dú)家記憶。 年前放假的最后一天,我們上線了「My Flyme 獨(dú)家記憶」 H5 活動(dòng)宣傳頁(yè)。 因種種原因,直到放假前幾天,才突然要求我們參與并開始項(xiàng)目的前端部分。此時(shí)大概的情況是:所有數(shù)據(jù)已計(jì)算完畢;后端接口已完成待聯(lián)調(diào);交互視覺只出了不到四分之一(一共二十多個(gè)頁(yè)面);我...
閱讀 2481·2021-11-19 09:59
閱讀 2005·2019-08-30 15:55
閱讀 938·2019-08-29 13:30
閱讀 1342·2019-08-26 10:18
閱讀 3090·2019-08-23 18:36
閱讀 2394·2019-08-23 18:25
閱讀 1168·2019-08-23 18:07
閱讀 441·2019-08-23 17:15