Недавно оптимизированные предыдущие проекты, разделенные с одностраничных на многостраничные, запишите здесь весь пошаговый процесс.
Разделить на несколько страниц
1. Замените одну страницу исходного проекта несколькими страницами.
здесь я добавил
index.htmlа такжеuser.htmlдве страницы.
2. Настройте vue.config.js
// vue.config.js
const titles = require('./title.js')
const glob = require('glob')
const pages = {}
glob.sync('./src/pages/**/main.js').forEach(path => {
const chunk = path.split('./src/pages/')[1].split('/main.js')[0]
pages[chunk] = {
entry: path,
template: 'public/index.html',
title: titles[chunk],
chunks: ['chunk-vendors', 'chunk-common', chunk]
}
})
module.exports = {
pages,
chainWebpack: config => config.plugins.delete('named-chunks'),
devServer: {
proxy: {
'/api': {
target: 'http://127.0.0.1:8080',
changeOrigin: true,
pathRewrite: { '^/api': '' }
}
}
}
}
может быть выполненvue inspectПосмотреть полную информацию о конфигурации:
Отложенная загрузка маршрута
vue-routerОфициальные примеры следующие, здесьwebpackChunkNameЕсли вы не запишете пакет, вместо него будет автоматически сгенерирован серийный номер.
//router/index.js
{
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')
},
Для того, чтобы облегчить отслеживание упаковки, лучше всего написать его, вы можете увидетьabout.[hash].jsувеличить размер.
Если вы хотите упаковать несколько маршрутов в один js, напишите один и тот жеwebpackChunkNameТолько что
{
path: '/another',
name: 'another',
// 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/Another.vue')
}
после упаковкиabout.jsФайл стал больше на 0.33Кб, и на одну страницу больше.
Внедрение анализа кода BundleAnalyzerPlugin
npm i webpack-bundle-analyzerПосле изменения конфигурации vue.config.js
//vue.config.js
const BundleAnalyzerPlugin = require("webpack-bundle-analyzer")
.BundleAnalyzerPlugin;
const report = process.env.npm_config_report;
module.exports = {
...
configureWebpack: config => {
if (report) {
config.plugins.push(new BundleAnalyzerPlugin());
}
},
...
}
опять такиpackage.jsonдобавлено в
"scripts": {
...
"analyze": "npm_config_report=true npm run build"
},
Здесь, контролируяnpm_config_reportдля отображения страницы анализа выполнитеnpm run analyzeВы можете увидеть упаковку
Извлечь сторонние плагины
Выше можно увидетьvue,vue-routerа такжеvuexЗанимают большую часть места, они не имеют никакого отношения к нашей актуальной разработке и не меняются часто, мы можем извлечь их отдельно, чтобы не было необходимости каждый раз переупаковывать, параллельная загрузка и кеширование значительно улучшат доступ при браузер получает доступ к эффективности.
Существует два распространенных метода оптимизации: один черезcdnсоответствоватьexternalsДля достижения второго через отдельную упаковку и соответствиеDllReferencePlugin.
Если коротко, то плюсов и минусов два:cdn+externals: Конфигурация простая, доступ к cdn возможен во всей среде.Если случайно вызвать метод внутри запакованного файла, это может привести к повторной упаковке;DllReferencePlugin: Конфигурация более сложная, и dll нужно генерить вручную.Все точки доступа к одной и той же dll, что не вызовет повторной упаковки.
Оптимизация с помощью «внешних»
1. Простой способ настройки
Самый простой способ сделать это — вручную добавить cdn вindex.htmlсередина
<body>
<div id="app"></div>
<script src="https://cdn.bootcss.com/vue/2.6.10/vue.min.js"></script>
<script src="https://cdn.bootcss.com/vue-router/3.1.3/vue-router.min.js"></script>
<script src="https://cdn.bootcss.com/vuex/3.1.1/vuex.min.js"></script>
</body>
затем вvue.config.jsобъяснил вexternalsпункт
configureWebpack: (config) => {
config.externals = {
vue: 'Vue',
vuex: 'Vuex',
'vue-router': 'VueRouter',
// 'alias-name': 'ObjName'
// 写法: 中划线: 上驼峰
}
},
На данный момент эти зависимости больше не упакованы.
2. Различайте среду разработки и формальную среду
После того, как вышеуказанный метод настроен, потому что введениеvue.min.js, приведет кVue DevToolНе могу использовать, что делать?
const isProduction = process.env.NODE_ENV === "production";
...
configureWebpack: (config) => {
if(isProduction){
config.externals = {
vue: 'Vue',
vuex: 'Vuex',
'vue-router': 'VueRouter',
// 'alias-name': 'ObjName'
// 写法: 中划线: 上驼峰
}
}
},
Используйте только в формальной средеexternalsМогу я? Да, но сообщается об ошибке:
Uncaught TypeError: Cannot redefine property: $router
Потому чтоindex.htmlбыл введен один раз вvue-router, если не поставитьexternals, определение будет повторяться.
Поэтому нам нужно только внедрить cdn в официальную среду и подкорректировать предыдущий код:
// vue.config.js
const cdn = {
css: [],
js: [
'https://cdn.bootcss.com/vue/2.6.10/vue.min.js',
'https://cdn.bootcss.com/vue-router/3.1.3/vue-router.min.js',
'https://cdn.bootcss.com/vuex/3.1.1/vuex.min.js',
],
}
module.exports={
...
chainWebpack: (config) => {
if (isProduction) {
// 生产环境注入cdn + 多页面
glob.sync("./src/pages/**/main.js").forEach(path => {
const chunk = path.split("./src/pages/")[1].split("/main.js")[0];
config.plugin("html-" + chunk).tap(args => {
args[0].cdn = cdn;
return args;
});
});
}
},
}
На этом шаге в многостраничном режиме есть яма, упоминает официальный представитель, ноПредложениеВозьми - будет не одинhtml-webpack-pluginэкземпляр, в то время какconfig.plugin()должны получать точныеpluginИмя, если вы стиснете зубы и будете следовать онлайн-учебнику, вы обязательно застрянете здесь. Это на самом деле довольно просто, покаvue inspect --pluginsты можешь видеть
Следующий,index.htmlПосле обработки параметров cdn все готово😝
<!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">
<title><%= htmlWebpackPlugin.options.title %></title>
<!-- 使用CDN的CSS文件 -->
<% for (var i in htmlWebpackPlugin.options.cdn && htmlWebpackPlugin.options.cdn.css) { %>
<link href="<%= htmlWebpackPlugin.options.cdn.css[i] %>" rel="preload" as="style" />
<link href="<%= htmlWebpackPlugin.options.cdn.css[i] %>" rel="stylesheet" />
<% } %>
<!-- 使用CDN的JS文件 -->
<% for (var i in htmlWebpackPlugin.options.cdn && htmlWebpackPlugin.options.cdn.js) { %>
<link href="<%= htmlWebpackPlugin.options.cdn.js[i] %>" rel="preload" as="script" />
<% } %>
</head>
<body>
<noscript>
<strong>We're sorry but vue-multiple-pages-demo doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
</noscript>
<div id="app"></div>
<% for (var i in htmlWebpackPlugin.options.cdn && htmlWebpackPlugin.options.cdn.js) { %>
<script src="<%= htmlWebpackPlugin.options.cdn.js[i] %>"></script>
<% } %>
<!-- built files will be auto injected -->
</body>
</html>
Оптимизация с помощью `dllPlugin`
упомянутое ранее также может быть использованоdllPluginоптимизировать, но если вы используетеchromeизVue DevTool,vueне могу вставитьdllPlugin.
1. Создатьwebpack.dll.conf.js
const path = require('path')
const webpack = require('webpack')
const {CleanWebpackPlugin} = require('clean-webpack-plugin')
// dll文件存放的目录
const dllPath = 'public/vendor'
module.exports = {
entry: {
core: ['vue-router','vuex'],
// other: [],
},
output: {
path: path.join(__dirname, dllPath),
filename: '[name].dll.js',
// vendor.dll.js中暴露出的全局变量名
// 保持与 webpack.DllPlugin 中名称一致
library: '[name]_[hash]',
},
plugins: [
// 清除之前的dll文件
// "clean-webpack-plugin": "^1.0.0" 注意版本不同的写法不同
// new CleanWebpackPlugin(['*.*'], {
// root: path.join(__dirname, dllPath),
// }),
// "clean-webpack-plugin": "^3.0.0"
new CleanWebpackPlugin(),
// 设置环境变量
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: 'production',
},
}),
// manifest.json 描述动态链接库包含了哪些内容
new webpack.DllPlugin({
path: path.join(__dirname, dllPath, '[name]-manifest.json'),
// 保持与 output.library 中名称一致
name: '[name]_[hash]',
context: process.cwd(),
}),
],
}
2. Предварительно скомпилировать dll
существуетpackage.jsonдобавлено в
script:{
...
"dll": "webpack -p --progress --config ./webpack.dll.conf.js"
}
бегатьnpm run dllты сможешьpublic/vendorDLL генерируется под.
3. ВwebpackОбъявите предварительно скомпилированный раздел в
после объявленияwebpackЭти DLL пропускаются при упаковке.
// vue.config.js
configureWebpack: config => {
if (isProduction) {
config.externals = {
vue: "Vue"
// vuex: "Vuex", 这些都改成dllPlugin编译
// "vue-router": "VueRouter"
// 'alias-name': 'ObjName'
// 写法: 中划线: 上驼峰
};
}
config.plugins.push(
// 名称要和之前的一致,可以继续扩展多个
...["core"].map(name => {
return new webpack.DllReferencePlugin({
context: process.cwd(),
manifest: require(`./public/vendor/${name}-manifest.json`)
});
})
);
},
4. Справочная DLL
Наконец, введениеindex.html, вы можете просто написать напрямую:
<script src=./vendor/core.dll.js></script>
Если вы хотите быть умнее, используйтеadd-asset-html-webpack-plugin, он будет генерировать вpublic/vendorПриведенная ниже dll автоматически вводится вindex.htmlсередина.
const AddAssetHtmlPlugin = require("add-asset-html-webpack-plugin");
config.plugins.push(
...
// 将 dll 注入到 生成的 html 模板中
new AddAssetHtmlPlugin({
// dll文件位置
filepath: path.resolve(__dirname, "./public/vendor/*.js"),
// dll 引用路径
publicPath: "./vendor",
// dll最终输出的目录
outputPath: "./vendor"
})
);
},
Готово!
наконец
DEMO
адрес:GitHub.com/Vita2333/vu…
КаждыйcommitВ соответствии с этапом конфигурации,vueиспользоватьexternalПредставлены, различая среды разработки и настройки, другиеvue-routerи т.д. используютсяdllPluginПредставлено, нуждающиеся друзья могут пойти и посмотреть :)
Ссылаться на
GitHub.com/PL или жесть US/V…
nuggets.capable/post/684490…
blog.CSDN.net/neo VE ee/art…