webpack4搭建vue多页面环境
总结一下webpack4配置vue开发环境,本文不具体介绍webpack的基本概念和用途,如有不了解的请参见https://www.webpackjs.com/concepts/官网
一、webpack基本环境配置
本机系统:centOS、node版本:v10.19.0、npm版本:6.13.4
1、创建项目
mkdir vuepro //创建项目目录
cd vuepro
npm init
npm init 之后一路回车创建好项目
2、配置webpack
npm i webpack webpack-cli -D
mkdir src //创建src和config目录,并创建对应文件
touch src/index.js
mkdir config
touch config/webpack.common.js
3、webpack.common.js文件基本配置
const path = require('path');
module.exports = {
mode:'development',
entry: path.resolve(__dirname,'../src/index.js'),
output: {
filename: '[name].[hash:4].js', // 打包后的文件名称
path: path.resolve(__dirname,'../dist') // 打包后的文件目录
}
}
并且在package.json中加上打包执行的文件:
index.js里随便写一些js内容如:
执行:
npm run build
控制台成功打包并输出在dist文件下
4、清空打包目录
npm i clean-webpack-plugin -D
const { CleanWebpackPlugin } = require('clean-webpack-plugin')
new CleanWebpackPlugin()
5、配置html模板
npm i html-webpack-plugin -D
const HtmlWebpackPlugin = require('html-webpack-plugin')
new HtmlWebpackPlugin({
title: 'index',
filename: 'index.html',
template:path.resolve(__dirname,'../template/index.html')
}) mkdir template
touch temloate/index.html
并在index.html中写入基本的html骨架,此时的webpack.common.js:
const path = require('path');
const { CleanWebpackPlugin } = require('clean-webpack-plugin')
const HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
mode:'development',
entry: path.resolve(__dirname,'../src/index.js'),
output: {
filename: '[name].[hash:4].js', // 打包后的文件名称
path: path.resolve(__dirname,'../dist') // 打包后的文件目录
},
plugins:[
new CleanWebpackPlugin(),
new HtmlWebpackPlugin({
title: 'index',
filename: 'index.html',
template:path.resolve(__dirname,'../template/index.html')
})
]
}
此时运行npm run build 在dist目录上应该生成一个html文件和一个js文件,并且js文件直接注入了html中
在浏览器打开index.html并打开控制台,就能看到我们在js里写的conso语句已经执行了
我们配置的mode:'development'在js里是能通过process.env.NODE_ENV获取到的;但是在配置文件里,我们是访问不到process.env.NODE_ENV的比如,在webpack.common.js加入
然后执行npm run build
可见在process.env里是没有NODE_ENV变量的
6、配置cross-env定义环境变量
npm i -D cross-env
//把package.json的buil改为
"build": "cross-env NODE_ENV=development webpack --config config/webpack.common.js"
此时在执行npm run build 配置文件里就能访问到process.env.NODE_ENV了
从这里开始不再一步一步搭建,而是直接使用我搭建好的配置,完整的配置地址:https://github.com/jiangconghu01/webpackpro.git
7、配置moudle处理css并分离
npm i style-loader css-loader mini-css-extract-plugin -D
const MiniCssExtractPlugin = require("mini-css-extract-plugin")
const isDev = process.env.NODE_ENV === 'development' module: {
rules: [
{
test: /\.css$/,
use: [
isDev ? 'style-loader' : MiniCssExtractPlugin.loader,
'css-loader'
]
}]
}
8 、处理js
可以转化es6之后新语法为浏览器可执行的es5语法,并且在使用新的api和内置对象可以自动polyfill;当然之前使用
1.import "babel-polyfill";
2.module.exports = {
entry: ["babel-polyfill", "./app/js"]
}
;
这种方式全局注入也是可以的,不过这里不使用这种方式
npm i babel-loader @babel/core @babel/preset-env @babel/plugin-transform-runtime -D
npm i core-js@2 -S
{
test: /\.js$/,
exclude: /(node_modules|bower_components)/,
use: {
loader: 'babel-loader',
options: {
presets:[
['@babel/preset-env',{"useBuiltIns": "usage","corejs": 2}]//这里要加[],要不会报错
],
plugins:["@babel/plugin-transform-runtime"]
}
}
},
具体的babel7的配置参考:https://juejin.im/post/5ddff3abe51d4502d56bd143
9、处理scss文件
npm i autoprefixer node-sass sass-loader postcss-loader -D
{
test: /\.scss$/,
use: [isDev ? 'style-loader' : MiniCssExtractPlugin.loader,
'css-loader',
{
loader:'postcss-loader',
options:{
plugins:[require('autoprefixer')]
}
},
'sass-loader'
]
}
并使用autoprefixer自动注入浏览器兼容前缀,配置之后在package.json中加入
browerslist配置就能自动注入前缀了,具体配置规则可以看https://www.npmjs.com/package/browserslist
10、处理图片,字体文件等配置
npm i url-loader file-loader -D
{
test: /\.(png|svg|jpg|jpeg|gif)$/,
use: [{
loader: 'url-loader',
options: {
esModule: false,
limit: 1024 * 3, // 3k一下的图片转为bs64编码
name: 'resources/[name].[hash:8].[ext]'
}
}
]
},
{
test: /\.(woff|woff2|eot|ttf|otf)$/,
use: [{
loader: 'file-loader',
options: {
limit: 1024,
name: 'resources/[name].[hash:8].[ext]'
}
}
11、使用开发服务器webpakc-dev-server
mode: 'development',
devServer: {
contentBase: path.join(__dirname, '../dist'),
index: 'proindex.html',
compress: true,
hot: true,
host: '0.0.0.0',
port: 9000,
proxy: {
'/czxt': {
target: 'http://39.105.122.153:3000',
changeOrigin: true,
secure: false
}
}
}
这里proxy配置改写不同接口和地址
12、处理vue文件
npm i vue-loader -D
const VueLoaderPlugin = require('vue-loader/lib/plugin')
new VueLoaderPlugin()
{
test:/\.vue$/,
use:['vue-loader']
}
13、配置resolve
配置可以省略后缀,还有经常饮用文件路径的别名,提高代码书写效率
resolve: {
extensions: [".json", ".js", ".jsx",".vue"],
alias: {
"@": path.join(__dirname, "../src"),
'pages': path.join(__dirname, "../src/pages")
}
}
14、配置打包显示进度和时间,配置打包分析结果
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
const ProgressBarPlugin = require('progress-bar-webpack-plugin')
new ProgressBarPlugin({ // 显示进度
format: chalk.green('Progressing') + '[:bar]' + chalk.green(':percent') + '(:elapsed seconds)',
clear: false
}),
new BundleAnalyzerPlugin({
openAnalyzer: false,
analyzerMode: 'static',
reportFilename: 'bundle_analyzer_report.html'
})
到这里基本配置的内容都差不多了
二、优化配置
1、为了减少打包体积,压缩文件
1.1、 压缩图片:之前的配置里,处理图片的url-loader对小图(limit限制大小)转化为base64编码减少请求,在此之前我们先使用mage-webpack-loader
对图片压缩
brew install libpng //先装libpng,brew是mac的安装工具
cnpm install image-webpack-loader -D//npm 没安成功,我换了cnpm
{
test: /\.(png|svg|jpg|jpeg|gif)$/,
use: [{
loader: 'url-loader',
options: {
esModule: false,
limit: 1024 * 3, // 3k一下的图片转为bs64编码
name: 'resources/[name].[hash:8].[ext]'
}
},
{ // 压缩图片
loader: 'image-webpack-loader',
options: {
disable: false
}
}]
}
可以对比小配置前后的打包大小,比如这个titile的png图片:不压缩之前
配置压缩以后:
原来10.5k,现在5.94k
1.2、 压缩css
npm i optimize-css-assets-webpack-plugin -D
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin')
new MiniCssExtractPlugin({
filename: 'css/[name].style.css'
}),
new OptimizeCSSAssetsPlugin({
assetNameRegExp: /\.style\.css$/g,
cssProcessor: require('cssnano'),
cssProcessorOptions: { safe: true, discardComments: { removeAll: true } },
canPrint: true
}),
根据前边的module里css和scss的配置
分离出来的css都放在(filename: 'css/[name].style.css')css文件夹下,并且有.style.css命名规则,所以配置压缩范围:assetNameRegExp: /\.style\.css$/g
1.3、 压缩js
webpack4直接配置
optimization:{
splitChunks: {
cacheGroups: { commons: {
name: "commons",
chunks: "initial",
minSize:0, //代码最小多大,进行抽离
minChunks:2, //代码复 2 次以上的抽离
priority: 1
},
vendors: {
test: /node_modules/,
name: 'vendors',
minSize: 0,
minChunks: 1,
chunks: 'initial',
priority: 10
}
}
}
}
提取所有node_modules里的库代码到vendors里,提取代码里的公共代码到common里,当然这样也有问题,在引入很多不同的库时候,就是vendors会很大
所以这里有两个问题:
1)、每次打包都要打包node_modules目录下引入的库和框架代码,打包速度特别慢
2)、vendors文件很大,页面加载慢,等待时间长
1、针对打包速度慢的问题,可以使用DllPlugin DllReferencePlugin插件将node_modules下的框架和库代码打包成一个文件,直接引入html模板里,这样只要版本不变,不用每次打包node_modules下的文件,提高了打包速度;但是没有解决vendors特别大的问题,当然也可以每个库单独打包引入,但是这样特别麻烦,多页面时候,每个html都要引入
2、针对vendors很大的问题,可以像下边这样把库都分开打包,分开引入,但是这样打包速度提不上了
还有就是引用cdn资源了,既能提高打包速度,又不用吧第三方库打包成很大的vendors,还能提高加载速度
在html中引入
然后配置
externals: {
'vue': 'Vue',
'vue-router': 'VueRouter',
'vuex': 'Vuex',
'echarts': 'echarts',
'axios': 'axios'
},
把项目文件里的这些库的引入全部去掉
原来打包速度:
不用打包框架和库代码之后:
3、多页配置
一般,在entry加多个入口,然后每个入口对应一个html,每次新加一个文件时候就在配置文件加一个入口,然后new一个HtmlWebpackPlugin,当页面很多时候你就得反复修改配置文件,所以我我们借助node的glob模块对项目下的文件进行遍历,动态输出配置入口和plugin
const glob = require('glob')
const path = require('path')
const entryFile = glob.sync(path.join(__dirname,'../src/*.js')) const HtmlWebpackPlugin=require('html-webpack-plugin'); const entry = {}
const htmlWebpackPlugins = []
entryFile.forEach(file => {
const filename = path.basename(file.split('/').pop(), '.js')
entry[filename] = [file],
htmlWebpackPlugins.push(
new HtmlWebpackPlugin({
title: filename,
chunks:['vendors','commons',filename],
template: path.resolve(__dirname,`../template/${filename}.html`),
filename: `${filename}.html`
})
)
})
console.log(entry)
module.exports = {
entry,
plugins:htmlWebpackPlugins
}
现在只要每次在src下创建入口文件,然后在template文件下创建对应的html模板文件就行。
4、懒加载的配置
npm i @babel/plugin-syntax-dynamic-import -D
{
test: /\.js$/,
exclude: /(node_modules|bower_components)/,
use: {
loader: 'babel-loader',
options: {
presets:[
['@babel/preset-env',{"useBuiltIns": "usage","corejs": 2,modules: false}]//这里要加[],要不会报错
],
plugins:["@babel/plugin-transform-runtime",'@babel/plugin-syntax-dynamic-import']
}
}
}
修改代码中如路由为动态加载
5、缓存打包结果,提高编译效率
npm i cache-loader -D
添加cache-loader之后再次启动开发环境也变快了,第二次编译只用了
当然,用了测试的这个demo项目就十多个文件,几百行代码
注:本次测试所有文件地址:https://github.com/jiangconghu01/webpackpro.git
最新文章
- [LeetCode] Number of Islands 岛屿的数量
- leetcode 186. Reverse Words in a String II 旋转字符数组 ---------- java
- Spring boot开发过程遇到的一些小问题
- 13个风格独特的关于页面(About Pages)设计
- Office 365 - SharePoint 2013 Online 在应用商店中添加应用
- search--搜索引擎的使用笔记
- javascript 正则 验证 第25节
- Java语言基础(七)
- 10.11 noip模拟试题
- Javascript数组操作方法
- UVA 1611 Crane
- 达内TTS6.0课件oop_day02
- 根据NSString字符串长度自动改变UILabel的frame
- 老李分享:Robotium编写测试用例如何模拟Junit4的BeforeClass和AfterClass方法1 - 条件判断法
- 计算进程消费cpu和内存
- &;lt;LeetCode OJ&;gt; 58. Length of Last Word
- OS X Yosemite升级提示升级OS10.11或更高版本问题解决方法
- JavaScript的基本使用
- [POI2015]CZA
- SSH框架下的表单重复提交