总结一下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直接配置

mode: 'production'
就能压缩js了
 
2、提取公共代码
      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

												

最新文章

  1. [LeetCode] Number of Islands 岛屿的数量
  2. leetcode 186. Reverse Words in a String II 旋转字符数组 ---------- java
  3. Spring boot开发过程遇到的一些小问题
  4. 13个风格独特的关于页面(About Pages)设计
  5. Office 365 - SharePoint 2013 Online 在应用商店中添加应用
  6. search--搜索引擎的使用笔记
  7. javascript 正则 验证 第25节
  8. Java语言基础(七)
  9. 10.11 noip模拟试题
  10. Javascript数组操作方法
  11. UVA 1611 Crane
  12. 达内TTS6.0课件oop_day02
  13. 根据NSString字符串长度自动改变UILabel的frame
  14. 老李分享:Robotium编写测试用例如何模拟Junit4的BeforeClass和AfterClass方法1 - 条件判断法
  15. 计算进程消费cpu和内存
  16. <LeetCode OJ> 58. Length of Last Word
  17. OS X Yosemite升级提示升级OS10.11或更高版本问题解决方法
  18. JavaScript的基本使用
  19. [POI2015]CZA
  20. SSH框架下的表单重复提交

热门文章

  1. 重读es6, 正确了解promise中catch的用法
  2. PyTorch可视化——tensorboard、visdom
  3. Andriod you must restart adb and eclipse
  4. JAVA SOCKET多线程等待接受客户端信息实现
  5. Hexo搭建静态博客踩坑日记(一)
  6. pytorch之 regression
  7. CentOS7及Docker配置中文字符集问题
  8. python2 + Django 中文传到模板页面变Unicode乱码问题
  9. THINKPHP-RCE-POC
  10. 珠峰-buffer-流事件