vue-cli3單頁構建大型專案方案
一、vue-cli3單頁面構建方案
1、在目標資料夾內執行
vue ui ; 一個ui版介面,用於建立vue專案;
2、開啟router資料夾內的index,看情況配置router的模式,是預設的hash還是history?ps:個人推介history模式,因為內嵌如app的H5頁面的話,有可能某些app是不允許頁面上帶有'#'的,而hash會在url上利用#來做路由轉發。ps:history模式在釋出到伺服器上需要nginx配置一下。詳情請自行百度。
const router = new VueRouter({ base: '/',mode: 'history',//還可設定為'hash'模式 routes })
3、在根目錄新建vue.config.js,覆蓋webpack配置,將如下內容copy到檔案中,作為初始配置
// const webpack = require('webpack') module.exports = { lintOnSave: false,// 禁止eslint devServer: { open: true,// 構建完成自動開啟瀏覽器 },configureWebpack: { plugins: [ // 全域性配置node_modules中的模組,使用時無需引入 new webpack.ProvidePlugin({ $: "jquery",jQuery: "jquery","windows.jQuery": "jquery" }) ] },// webpack 連結 API,用於生成和修改 webapck 配置 chainWebpack: (config) => { // 取消 chunks,每個頁面只對應一個單獨的 JS / CSS config.optimization.splitChunks({ cacheGroups: {} }); // config // .plugin('webpack-bundle-analyzer') // .use(require('webpack-bundle-analyzer').BundleAnalyzerPlugin) },pluginOptions: { } }
4、配置完這些後,npm run serve啟動專案,會載入如下兩個js
npm run serve
app.js:是所有單頁面首次渲染都必須載入的js,內部合併了框架及js(如vue、vue-x、vue-router及非非同步元件但引用了的node_modules中的模組),及所有頁面公用的模組。about.js:是每個頁面獨立的js,這個跟router中引用模組的方式有關。
具體詳解如下:
1、
import Home from '../views/Home.vue'
這種引用方式引用頁面模版元件,就不會出現about.js檔案,因為屬於同步模組,當前件建的js會被打包進app.js。但是此種隨著頁面的增多,公用的app.js會越來越大。看情況在app.js大小接受的前提下權衡使用;2、
const routes = [ { path: '/',name: 'Home',// component: Home component: () => import(/* webpackChunkName: "home" */ '../views/Home.vue') // webpack的魔法註釋,將拆分出的js命名為home },{ path: '/about',name: 'About',// route level code-splitting // this generates a separate chunk (about.[hash].js) for this route // which is lazy-loaded when the route is visited. component: () => import(/* webpackChunkName: "about" */ '../views/About.vue') } ]
這種引用方式就是非同步引用模版元件,不會將當前組建的js打包進app.js,就不會出現1種的問題。因為只要沒有載入到對應頁面,就不會載入對應頁面的js。對應頁面的js會最為獨立的js單獨的動態引入,如同上圖的about.js,在進入about頁面時才會引入。
3、如果在main.js中引入的node_modules包,則會直接打包進app.js,這個逃不掉。
ps:最終結論,建議每個頁面都非同步引用頁面模版。
5、每個頁面如果引了node_mudules就會存在相對應的vendors-home.js,如果沒引入node_mudules的話,每個頁面按需元件就不會存在vendors-home.js這個檔案,如下圖:
6、區分本地、測試、線上環境
ps:官網提供一種方案,但是需要建立多個環境配置的配置檔案,嫌麻煩,就不使用官方的方式,使用如下外掛拆分環境:
cross-env:https://github.com/kentcdodds/cross-env
cnpm i cress-env --save-dev // 更改node環境變數外掛
之後在package.json中加入如下三行配置,即可區分本地、測試、線上環境
"scripts": { "serve": "cross-env NODE_ENV=development vue-cli-service serve","test": "cross-env NODE_ENV=test vue-cli-service build","build": "cross-env NODE_ENV=production vue-cli-service build" },
在vue.config.js中執行如下程式碼即可打印出當前環境。
console.log(process.env.NODE_ENV)
在src目錄下新建config目錄,進入目錄,新建gateway.config.js檔案用於配置不同環境介面host,程式碼如下:gateway.config.js檔案內容如下:
// 開發環境地址(npm run serve) const devHost = { // 介面地址域名相關 baseApi: 'https://abc.com',} // 測試環境地址(npm run test) const testHost = { // 介面地址域名相關 baseApi: 'https://abc.com',} // 線上環境地址(npm run build) const proHost = { // 介面地址域名相關 baseApi: 'https://abc1.com',} // 區分環境選擇靜態資源地址 const env = process.env.NODE_ENV let exportConfig = '' if (env === 'production') { exportConfig = proHost } else if (env === 'test') { exportConfig = testHost } else { exportConfig = devHost } export default exportConfig
結束:之後只需要在介面api的js檔案中引入此檔案即可。釋出時區分環境打包。
7、淺談專案引入第三方外掛方案
ps:原則:移動端單個js大小不超過200k;pc端單個js不超過400k;
1.vue模組化引入node_modules包外掛:
前提,各個頁面都是非同步載入,這樣的好處是單個頁面的js不會被打包進公共app.js中。之後在單個js中引入第三方庫。但是據測試:這種模組化引入第三方外掛,比cdn模式引入的js體積至少要大2唄,因為webpack內部對每個第三方庫進行了二次處理,會增大js體積。權衡js大小使用。
2.cdn模式引入第三方外掛:
提供這種方式,是因為有些庫是不支援vue的,只支援cdn模式引入,而且比較輕量級,可以選擇這種方案,非同步cdn模式引入第三方外掛,這些方式最下方腳手架示例中都有demo;
8、專案中常用的打包外掛及第三方庫
1.vue https://cn.vuejs.org
2.vue-router https://router.vuejs.org
3.vue-x https://vuex.vuejs.org
4.sass https://www.sass.hk
5.axios http://www.axios-js.com/
6.normalize.css http://necolas.github.io/normalize.css/
7.n-zepto https://npm.taobao.org/package/n-zepto
8.webpack-bundle-analyzer https://github.com/webpack-contrib/webpack-bundle-analyzer
下方是vue-cli3內建外掛(直接在vue.config.js中配置):
如下外掛可參考vue-cli3官網配置方法:
https://cli.vuejs.org/zh/config/#css-sourcemap
9.autoprefixer:自動新增瀏覽器字首。(如:-webkit-等)
10.url-loader:改變靜態資源引用路徑
11.ProvidePlugin:全域性配置node_modules中的模組
具體配置方法如下(比較全的vue.config.js配置):
const webpack = require('webpack') const processEnv = process.env.VUE_APP_ENV; // 區分環境(值:production、development、test) const isPro = processEnv === 'production'; // 判斷production環境 const outputDir = 'dist'; // 輸出檔案目錄(預設dist) const assetsDir = ''; // 配置放置生成的靜態資源 (js、css、img、fonts) 的 (相對於 outputDir 的) 目錄 // 區分環境選擇cdn地址 let publicPath = '' // 靜態資源引用路徑 let fontPublicPath = '' // 字型圖示引用的cdn路徑 let imgPublicPath = '' // css引用圖片的cdn路徑(c2c/static/img) if (processEnv === 'production') { publicPath = 'https://abc.com/c2c/shop' // 正式環境靜態資源css、js等cdn路徑 fontPublicPath = `https://abc.com/c2c/shop/${assetsDir ? assetsDir + '/' : '/'}fonts` // 正式環境字型圖示引用的cdn路徑 imgPublicPath = `https://abc.com/c2c/shop/${assetsDir ? assetsDir + '/' : '/'}/img` // 正式環境css引用圖片的cdn路徑 } else if (processEnv === 'test') { // publicPath = './' // 正式環境靜態資源css、js等cdn路徑 publicPath = 'https://bcd.com/c2c/shop/dist' // 測試環境靜態資源css、js等cdn路徑 fontPublicPath = '' imgPublicPath = '' } else { publicPath = '/' fontPublicPath = '' imgPublicPath = '' } const devServerHost = 'localhost'; const devServerPort = '8080'; // 埠號 const devServerOpen = true; // 熱啟動後自動開啟瀏覽器 module.exports = { // 配置生成dist裡面static的cdn資源路徑(測試環境為./,正式環境走cdn路徑) publicPath: publicPath,// 輸出檔案目錄(預設dist) outputDir,// 配置放置生成的靜態資源 (js、css、img、fonts) 的 (相對於 outputDir 的) 目錄 assetsDir,devServer: { host: devServerHost,port: devServerPort,open: devServerOpen,// 構建完成自動開啟瀏覽器 // eslint檢測影響程式碼編譯,註釋調不會影響程式碼編譯 // overlay: { // warnings: true,// errors: true // } },lintOnSave: processEnv === 'development' ? true : false,// 開發環境開啟eslint,測試和線上編輯程式碼禁止eslint // webpack 配置,鍵值物件時會合並配置,為方法時會改寫配置 configureWebpack: config => { // 擴充套件資源,不將部分資源js等打入包內引用cdn資源 let externals = { // 'swiper': 'Swiper',}; config.externals = externals; //警告 webpack 的效能提示 config.performance = { hints: isPro ? 'warning' : false,// 本地開發不顯示警告 // 入口起點的最大體積 maxEntrypointSize: 512000,// 500kib // 生成檔案的最大體積 maxAssetSize: 307200,// 300kib // 只給出 js 檔案的效能提示 assetFilter(assetFilename) { return assetFilename.endsWith('.js'); } }; },// webpack 連結 API,用於生成和修改 webapck 配置 chainWebpack: (config) => { // 取消 chunks,每個頁面只對應一個單獨的 JS / CSS config.optimization.splitChunks({ cacheGroups: {} }); // 全域性配置node_modules中的模組,使用時無需引入 config.plugin('provide').use(webpack.ProvidePlugin,[{ $: "n-zepto",Zepto: "n-zepto","window.Zepto": "n-zepto" }]); config.module .rule('images') .use('url-loader') .loader('url-loader') .tap(options => Object.assign(options,{ limit: 10240,// 小於10k,壓縮圖片 => base64 // limit: 3000,publicPath: imgPublicPath,name: `[name].[hash:8].[ext]` })) // 設定fonts字型檔案引用的路徑 config.module .rule('fonts') .test(/\.(woff2?|eot|ttf|otf)(\?.*)?$/i) .use('url-loader') .loader('file-loader') .tap(options => Object.assign(options,{ limit: 5000,publicPath: fontPublicPath,name: '[name].[hash:8].[ext]' })) // npm run report;列印app.js的模組報告,檢視各個模組; if (processEnv === 'report') { config .plugin('webpack-bundle-analyzer') .use(require('webpack-bundle-analyzer').BundleAnalyzerPlugin) } },// css配置處理 css: { // 是否使用css分離外掛 ExtractTextPlugin;true:頁面css獨立分割,false:頁面css同一打包; extract: true,// 開啟 CSS source maps(預設false)線上關閉,測試和本地開啟 sourceMap: isPro ? false : true,// css預設器配置項 loaderOptions: { sass: { // sass的公共方法和變數,需要預編譯; prependData: ` @import "@/assets/css/global.scss"; @import "@/assets/css/func.scss"; ` },postcss: { plugins: [ // 瀏覽器自動加字首 require('autoprefixer')({ overrideBrowserslist: [ "Android 4.0","iOS 7","Chrome > 31","ff > 31","ie >= 8" ] }),] } },// 啟用 CSS modules for all css / pre-processor files. requireModuleExtension: false },// 構建時開啟多程序處理 babel 編譯 parallel: require('os').cpus().length > 1,pwa: { iconPaths: { favicon32: 'favicon.ico',favicon16: 'favicon.ico',appleTouchIcon: 'favicon.ico',maskIcon: 'favicon.ico',msTileImage: 'favicon.ico' },},// 第三方外掛配置 pluginOptions: { // ... } }
9、一個基礎配置較為完善的基於vue-cli3的單頁面專案方案腳手架:
專案腳手架集合project-init
其中的cli-start-spa資料夾,內部readme有專案細節。
到此這篇關於vue-cli3單頁構建大型專案方案的文章就介紹到這了,更多相關vue-cli3單頁構建 內容請搜尋我們以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援我們!