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直接配置

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 

 

 

 

 

 

 

 

 


 

posted @ 2020-02-24 18:27  逸丶风  阅读(1293)  评论(0编辑  收藏  举报