vue-cli3.0如何使用CDN區(qū)分開(kāi)發(fā)、生產(chǎn)、預(yù)發(fā)布環(huán)境
前言:上一篇記錄文vue-cli 3.0 build包太大導(dǎo)致首屏過(guò)長(zhǎng)的解決方案中提到了CDN優(yōu)化,之前是直接在html中手動(dòng)注入JS,也沒(méi)有對(duì)開(kāi)發(fā)和生產(chǎn)模式進(jìn)行區(qū)分,因?yàn)槭鞘褂檬召M(fèi)的CDN,所以在開(kāi)發(fā)模式會(huì)遇到無(wú)權(quán)使用CDN的問(wèn)題。要是使用CDN寫(xiě)死在html中,不同環(huán)境需要手動(dòng)的切換CDN,那么早晚有一天會(huì)搞亂,下面就說(shuō)說(shuō)怎么在vue-cli 3.0 中根據(jù)不同環(huán)境動(dòng)態(tài)注入CDN。
1. 修改public/index.html
通過(guò)htmlwebpackplugin動(dòng)態(tài)注入腳本和樣式,index.html如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<link rel="icon" href="<%= BASE_URL %>favicon.ico" rel="external nofollow" >
<title>杭州納舍科技</title>
<!-- 使用CDN的CSS文件 -->
<% for (var i in htmlWebpackPlugin.options.cdn && htmlWebpackPlugin.options.cdn.css) { %>
<link href="<%= htmlWebpackPlugin.options.cdn.css[i] %>" rel="external nofollow" rel="external nofollow" rel="preload" as="style">
<link href="<%= htmlWebpackPlugin.options.cdn.css[i] %>" rel="external nofollow" rel="external nofollow" rel="stylesheet">
<% } %>
<!-- 使用CDN的JS文件 -->
<% for (var i in htmlWebpackPlugin.options.cdn && htmlWebpackPlugin.options.cdn.js) { %>
<link href="<%= htmlWebpackPlugin.options.cdn.js[i] %>" rel="external nofollow" rel="preload" as="script">
<% } %>
</head>
<body>
<noscript>
<strong>We're sorry but ui doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
</noscript>
<div class="global-loading">
<div class="spinner"></div>
</div>
<div id="app"></div>
<!-- built files will be auto injected -->
<% for (var i in htmlWebpackPlugin.options.cdn && htmlWebpackPlugin.options.cdn.js) { %>
<script src="<%= htmlWebpackPlugin.options.cdn.js[i] %>"></script>
<% } %>
</body>
</html>
2. 修改vue.config.js配置
首先我們會(huì)考慮哪些東西要進(jìn)行CDN優(yōu)化,例如我們需要把vue、vue-router、moment在構(gòu)建的時(shí)候排除在外使用CDN加載這三個(gè)庫(kù),那么需要把添加externals
const isProduction = process.env.NODE_ENV === 'production';
module.exports = {
configureWebpack: config => {
if (isProduction) {
config.externals = {
'vue': 'Vue',
'vue-router': 'VueRouter',
'moment': 'moment'
}
}
}
}
現(xiàn)在我們運(yùn)行npm run build 打包出來(lái)的文件就沒(méi)有Vue、VueRouter、moment,現(xiàn)在我們使用html-webpack-plugin插件進(jìn)行動(dòng)態(tài)注入CDN,在vue-cli 3.0 中我們要這樣配置:
const isProduction = process.env.NODE_ENV === 'production';
const cdn = {
css: ['xxx.css', 'sss.js'],
js: ['xxxx.js', 'sss.js']
}
module.exports = {
configureWebpack: config => {
if (isProduction) {
config.externals = {
'vue': 'Vue',
'vue-router': 'VueRouter',
'moment': 'moment'
}
}
}
chainWebpack: config => {
if (isProduction) {
config.plugin('html')
.tap(args => {
args[0].cdn = cdn;
return args;
})
}
}
}
到目前為止已經(jīng)解決了開(kāi)發(fā)模式不使用CDN,生產(chǎn)模式使用CDN的問(wèn)題和動(dòng)態(tài)在html中注入CDN的問(wèn)題。
可能你會(huì)遇到和我一樣的問(wèn)題
預(yù)發(fā)布build測(cè)試,但無(wú)權(quán)使用生產(chǎn)上的CDN問(wèn)題,那么我們必須再添加一個(gè)環(huán)境變量來(lái)區(qū)分預(yù)發(fā)布build的模式。(vue-cli 3.0 環(huán)境變量文檔)這里我添加一個(gè)IS_LOCAL_BUILD,首先我們?cè)趘ue.cofnig.js同路徑下創(chuàng)建一個(gè).en.production.local :
// .en.production.local` 內(nèi)容: IS_LOCAL_BUILD = 'isLocalBuild'
修改vue.config.js如下:
const isProduction = process.env.NODE_ENV === 'production';
const isLocalBuild = process.env.IS_LOCAL_BUILD === 'isLocalBuild';
const JS_CDN = isLocalBuild ? [
預(yù)發(fā)布CDN(例如那些免費(fèi)的CDN)
] : [
生產(chǎn)環(huán)CDN
];
const CSS_CDN = isLocalBuild ? [預(yù)發(fā)布CDN]: [生產(chǎn)CDN]
const cdn = {
css: CSS_CDN,
js: JS_CDN
}
module.exports = {
configureWebpack: config => {
if (isProduction) {
config.externals = {
'vue': 'Vue',
'vue-router': 'VueRouter',
'moment': 'moment'
}
}
}
chainWebpack: config => {
if (isProduction) {
config.plugin('html')
.tap(args => {
args[0].cdn = cdn;
return args;
})
}
}
}
ok,上面區(qū)分了生產(chǎn)、預(yù)發(fā)布和開(kāi)發(fā)環(huán)境使用CDN的問(wèn)題,這樣就不用根據(jù)不同環(huán)境手動(dòng)去修改CDN了。不過(guò)又一點(diǎn)要注意:⚠️預(yù)發(fā)布版本的構(gòu)建才需要添加.en.production.local。
完整的vue.config.js(供參考)
const path = require('path');
const CompressionWebpackPlugin = require('compression-webpack-plugin');
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
const productionGzipExtensions = ['js', 'css'];
const isProduction = process.env.NODE_ENV === 'production';
function resolve(dir) {
return path.join(__dirname, dir);
}
// 預(yù)發(fā)布環(huán)境
const isLocalBuild = process.env.IS_LOCAL_BUILD === 'isLocalBuild';
console.log('前端文件預(yù)發(fā)布打包- isLocalBuild:', isLocalBuild);
// 非externals CND前綴設(shè)置
const CDN_URL = isLocalBuild ? '/' : '//s.zypj.nasetech.com/';
// 區(qū)分生產(chǎn)環(huán)境打包和預(yù)發(fā)布打包,使用不同的CDN
const JS_CDN = isLocalBuild ? [
// 預(yù)發(fā)布CDN
] : [
// 生產(chǎn)CDN
];
const cdn = {
// css: [],
js: JS_CDN
}
module.exports = {
lintOnSave: true,
baseUrl: isProduction ? CDN_URL : '/',
chainWebpack: (config) => {
// build打包才使用CDN
if (isProduction) {
config.plugin('html')
.tap(args => {
args[0].cdn = cdn;
return args;
})
}
config.resolve.alias
.set('assets', resolve('src/assets'))
.set('pages', resolve('src/pages'))
.set('components', resolve('src/components'))
.set('utils', resolve('src/utils'))
},
devServer: {
host: '0.0.0.0',
port: 8080,
https: false,
hotOnly: false,
disableHostCheck: false,
proxy: {
'/api/v0/': {
// 目標(biāo) API 地址
target: 'http://127.0.0.1:4545',
// 將主機(jī)標(biāo)頭的原點(diǎn)更改為目標(biāo)URL
changeOrigin: true,
},
},
},
configureWebpack: config => {
// 生產(chǎn)模式
if (isProduction) {
config.externals = {
'vue': 'Vue',
'vue-router': 'VueRouter',
'moment': 'moment'
}
// 打包生產(chǎn).gz包
config.plugins.push(new CompressionWebpackPlugin({
algorithm: 'gzip',
test: new RegExp('\\.(' + productionGzipExtensions.join('|') + ')$'),
threshold: 10240,
minRatio: 0.8
}))
// 添加自定義代碼壓縮配置
config.plugins.push(
new UglifyJsPlugin({
uglifyOptions: {
compress: {
warnings: false,
drop_debugger: true,
drop_console: true,
},
},
sourceMap: false,
parallel: true,
})
)
}
}
}
* 使用CDN一些有意思的坑:
使用CDN還會(huì)遇到一些有意思的事,例如使用beta版的vue導(dǎo)致element UI庫(kù)有些組件無(wú)法正常工作; 使用免費(fèi)的CDN上線沒(méi)有多久就GG不能用等悲慘故事?。?!
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
vue-cli創(chuàng)建項(xiàng)目ERROR?in?Conflict:?Multiple?assets?emit?dif
最近vue/cli創(chuàng)建項(xiàng)目后出現(xiàn)了錯(cuò)誤,下面這篇文章主要給大家介紹了關(guān)于vue-cli創(chuàng)建項(xiàng)目ERROR?in?Conflict:?Multiple?assets?emit?different?content?to?the?same?filename?index.html問(wèn)題的解決辦法,需要的朋友可以參考下2023-02-02
vue-quill-editor的使用及個(gè)性化定制操作
這篇文章主要介紹了vue-quill-editor的使用及個(gè)性化定制操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-08-08
Vue項(xiàng)目保存代碼之后頁(yè)面自動(dòng)更新問(wèn)題
這篇文章主要介紹了Vue項(xiàng)目保存代碼之后頁(yè)面自動(dòng)更新問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-10-10
詳解vue-cli + webpack 多頁(yè)面實(shí)例應(yīng)用
本篇文章主要介紹了詳解vue-cli + webpack 多頁(yè)面實(shí)例應(yīng)用,具有一定的參考價(jià)值,有興趣的可以了解一下2017-04-04
基于vue cli 通過(guò)命令行傳參實(shí)現(xiàn)多環(huán)境配置
這篇文章主要介紹了vue項(xiàng)目通過(guò)命令行傳參實(shí)現(xiàn)多環(huán)境配置(基于@vue/cli)的相關(guān)資料,需要的朋友可以參考下2018-07-07
在vs code 中如何創(chuàng)建一個(gè)自己的 Vue 模板代碼
這篇文章主要介紹了在vs code 中如何創(chuàng)建一個(gè)自己的 Vue 模板代碼,本文通過(guò)圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-11-11
vue項(xiàng)目如何引入json數(shù)據(jù)
這篇文章主要介紹了vue項(xiàng)目如何引入json數(shù)據(jù),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-10-10

