基于vuecli2脚手架搭建项目
运行 npm run build --report 分析文件大小参考文档
步骤(快速搭建):
1、npm install -g @vue/cli-init
2、vue init webpack my-project
3、cd my-project
4、npm run dev
基于脚手架优化
//基本使用
const Foo = () => import('./Foo.vue');
const router = new VueRouter({
routes: [
{ path: '/foo', component: Foo }
]
})
2.定义绝对路径
在webpack.base.conf.js文件中,我们可以在resolve中对项目的绝对路径进行定义
resolve: {
extensions: ['.js', '.vue', '.json'],
alias: {
'@': resolve('src'),
'components': resolve('src/components'),
'pages': resolve('src/pages')
}
}
3.去掉打包生成的map文件(Source Maps只是方便调试,需要线上调试bug可以开启)
config/index.js修改
build下的productionSourceMap:false
4.所用的库尽量不要全局引入,可以按需加载(elementUI,echarts等)
elementUI 按需引入参考文档
//首先,安装 babel-plugin-component:
npm install babel-plugin-component -D
//然后,将 .babelrc 修改为:
{
"presets": [
["env", {
"modules": false,
"targets": {
"browsers": ["> 1%", "last 2 versions", "not ie <= 8"]
}
}],
"stage-2"
],
"plugins": ["transform-vue-jsx", "transform-runtime",["component",{
"libraryName": "element-ui",
"styleLibraryName": "theme-chalk"
}
]]
}
//接下来,如果你只希望引入部分组件,比如 Button 和 Select,那么需要在 main.js 中写入以下内容:
import { Button, Select } from 'element-ui';
Vue.use(Button)
Vue.use(Select)
//组件中使用
import {Button} from "element-ui";
export default {
name: 'App',
components:{
Button
}
}
<Button type="primary">按钮</Button>
echarts按需引入参考文档
1. 全局引入
npm install echarts -D
在mian.js中
import echarts from 'echarts' //引入echarts
Vue.prototype.$echarts = echarts //引入组件
2. 按需引入
//引入基本模板
let echarts = require('echarts/lib/echarts')
// 引入折线图等组件
require('echarts/lib/chart/line')
require('echarts/lib/chart/bar')
require('echarts/lib/chart/radar')
// 引入提示框和title组件,图例
require('echarts/lib/component/tooltip')
require('echarts/lib/component/title')
require('echarts/lib/component/legend')
require('echarts/lib/component/legendScroll')//图例翻译滚动
Vue.prototype.$echarts = echarts
5.引入DllPlugin分离第三方依赖,(另外一种方式cdn:暂时不做考虑,公司业务的原因)
在使用webpack进行打包时候,对于依赖的第三方库,比如vue,vuex等这些不会修改的依赖,我们可以让它和我们自己编写的代码分开打包,这样做的好处是每次更改我本地代码的文件的时候,webpack只需要打包我项目本身的文件代码,而不会再去编译第三方库,那么第三方库在第一次打包的时候只打包一次,以后只要我们不升级第三方包的时候,那么webpack就不会对这些库去打包,这样的可以快速的提高打包的速度。因此为了解决这个问题,DllPlugin
和 DllReferencePlugin插件就产生了。
在项目根文件创建webpack_dll.config.js
//项目前引入包文件
首先执行:npm i clean-webpack-plugin add-asset-html-webpack-plugin -D
const path = require('path');
const webpack = require('webpack');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
module.exports = {
// mode: 'production',
entry: {
//'element-ui'用按需引入方式这里就不打成第三方包了
vendor: ['vue/dist/vue.esm.js','vue-router']
},
output: {
// 指定生成文件所在目录
// 由于每次打包生产环境时会清空 dist 文件夹,因此这里我将它们存放在了 public 文件夹下
path: path.resolve(__dirname, 'public/vendor'),
// 指定文件名
filename: '[name].dll.js',
// 存放动态链接库的全局变量名称,例如对应 lodash 来说就是 lodash_dll_lib
// 这个名称需要与 DllPlugin 插件中的 name 属性值对应起来
// 之所以在前面 _dll_lib 是为了防止全局变量冲突
library: '[name]_dll_lib'
},
plugins: [
new CleanWebpackPlugin({
context: __dirname,
cleanOnceBeforeBuildPatterns: ['public/vendor']
}),
// 接入 DllPlugin
new webpack.DllPlugin({
// 描述动态链接库的 manifest.json 文件输出时的文件名称
// 由于每次打包生产环境时会清空 dist 文件夹,因此这里我将它们存放在了 public 文件夹下
path: path.join(__dirname, 'public', 'vendor', '[name].manifest.json'),
// 动态链接库的全局变量名称,需要和 output.library 中保持一致
// 该字段的值也就是输出的 manifest.json 文件 中 name 字段的值
// 例如 lodash.manifest.json 中就有 "name": "lodash_dll_lib"
name: '[name]_dll_lib'
})
]
};
修改package.json文件,加入dll命令
"scripts": {
"dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js",
"start": "npm run dev",
"build": "node build/build.js",
"dll": "webpack --config ./webpack_dll.config.js"
}
运行npm run dll
public就会生一个文件夹(vendor)包含两个文件(vendor.dll.js 和vendor.manifest.json);
//然后修改
build文件夹下的webpack.prod.conf.js
const AddAssetHtmlPlugin = require('add-asset-html-webpack-plugin');
plugins: [
// // 引用 manifest.json
new webpack.DllReferencePlugin({
manifest: require('../public/vendor/vendor.manifest.json')
}),
// // 将 dll 注入到 生成的 html 模板中
new AddAssetHtmlPlugin({
// 要添加到编译中的文件的绝对路径,以及生成的HTML文件。支持globby字符串
filepath: path.resolve(__dirname, '../public/vendor/*.js'),
// 文件输出目录
outputPath: 'vendor',
// 脚本或链接标记的公共路径
publicPath: 'vendor',
includeSourcemap: false
}),
//拷贝到dist文件夹下去
new CopyWebpackPlugin([
{
from: path.resolve(__dirname, '../public/vendor'),
to: config.build.assetsSubDirectory,
ignore: ['.*']
}
])
...
];
//然后运行npm run build 会报错,Cannot read property 'compilation' of undefined
原因是你现在安装add-asset-html-webpack-plugin的版本是3.1.3是基于webpack4的,而我们的项目是基于webpack3的所以需要降版本
npm uninstall --save-dev add-asset-html-webpack-plugin
npm install add-asset-html-webpack-plugin@2.1.3 --save-dev
然后执行npm run build就OK了
6.HappyPack优化打包速度(项目越大越明显)
由于运行在 Node.js 之上的 Webpack 是单线程模型的,所以Webpack 需要处理的事情需要一件一件的做,不能多件事一起做。
我们需要Webpack 能同一时间处理多个任务,发挥多核 CPU 电脑的威力,HappyPack 就能让 Webpack 做到这点,它把任务分解给多个子进程去并发的执行,子进程处理完后再把结果发送给主进程。
安装 HappyPack
npm i -D happypack
修改build文件夹下的webpack.base.conf.js 文件
const HappyPack = require('happypack');
const os = require('os');
const happyThreadPool = HappyPack.ThreadPool({ size: os.cpus().length });
module.exports = {
module: {
rules: [
{
test: /\.js$/,
//把对.js 的文件处理交给id为happyBabel 的HappyPack 的实例执行
loader: 'happypack/loader?id=happyBabel',
//排除node_modules 目录下的文件
exclude: /node_modules/
},
]
},
plugins: [
new HappyPack({
//用id来标识 happypack处理那里类文件
id: 'happyBabel',
//如何处理 用法和loader 的配置一样
loaders: [{
loader: 'babel-loader?cacheDirectory=true',
}],
//共享进程池
threadPool: happyThreadPool,
//允许 HappyPack 输出日志
verbose: true,
})
]
}
7.开启 Gzip 压缩(需要后台配合tomcat或者Nginx)
config文件夹下的index.js文件
build:{
productionGzip:true
}
- 在 Loader 配置中,所有文件的处理都交给了 happypack/loader 去处理,使用紧跟其后的 querystring ?id=babel 去告诉 happypack/loader 去选择哪个 HappyPack 实例去处理文件。
- 在 Plugin 配置中,新增了两个 HappyPack 实例分别用于告诉 happypack/loader 去如何处理 .js 和 .css 文件。选项中的 id 属性的值和上面 querystring 中的 ?id=babel 相对应,选项中的 loaders 属性和 Loader 配置中一样。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。