webpack学习总结

511 阅读2分钟

前言

之前系统的学习了一遍webpack,但一直没有时间好好的整合归纳,在此,将之前学习webpack的笔记以及相关知识点记录在此,相关代码已上传至github

以下是webpack构建的思维导图:

webpack结构

首先我们需要了解webpack构建的一个文件结构

  • entry
  • output
  • loaders
  • plugins
  • mode

entry

入口文件

modules.exports = {
  // 指定打包入口
  entry: './src/main.js', // 单入口文件 
  
  // 多入口文件
  // entry: {
  //   app: './src/app.js',
  //   adminApp: './src/adminApp.js'
  // }
}

output

打包后的文件存放文章

module.export = {
   output : {
    filename: '[name].js', // name相当于通配符
    path: path.join(__dirname,'dist')
  }
}

loaders

主要用于处理webpack不能解析的文件

module.export = {
   module: {
        /* * 【改动】:loader的使用中,loaders字段变为rules,用来放各种文件的加载器,用rules确实更为贴切 */
        rules: [
            // 引入css
            // npm install --save-dev css-loader style-loader
            {
                test: /.css$/,
                // loader: 'style-loader!css-loader'
                use: ['style-loader', 'css-loader'] // 上述格式不正确,加载多个插件,需要用use
            },
            /* * 【改动】:模板文件的加载方式变化 */ // 模板文件的处理
            {
                test: /.string$/,
                use: { loader: 'html-loader', options: { minimize: true, removeAttributeQuotes: false } }
            },
            /* * 【改动】:图片文件的加载方式变化,并和字体文件分开处理 */ // 图片的配置
            {
                test: /.(png|jpg|gif)$/,
                use: [{
                    loader: 'url-loader',
                    options: {/* * 【改动】:图片小于2kb的按base64打包 */ limit: 2048, name: 'resource/[name].[ext]' }
                }]
            },
            /* * 【改动】:字体文件的加载方式变化 */ // 字体图标的配置
            {
                test: /.(eot|svg|ttf|woff|woff2|otf)$/,
                use: [{ loader: 'url-loader', options: { limit: 8192, name: 'resource/[name].[ext]' } }]
            },
            // 引入对.vue文件的使用
            // npm install --save-dev vue-loader vue-template-compiler
            {
                test: /.vue$/,
                loader: 'vue-loader'
            }
        ]
    }, 
}

plugins

主要用于打包优化,资源管理和环境变量的注入

常见的plugin有如下:

名称描述
CommonChunksPlugin将chunks相同模块代码提取成公共js
CleanWebpackPlugin清理构建目录
ExtractTextWebpackPlugin将css从打包文件里提取成一个独立的css文件
CopyWebpackPlugin将文件或文件夹copy到构建的输出目录
HtmlWebpackPlugin创建html去承载输出的打包文件
UglifyjsWebpackPlugin压缩js
ZipWebpackPlugin将打包出的资源生成一个zip包

常用的loaders及plugin

Scop Hoisting 解决打包代码大量闭包

作用:减少函数声明代码和内存开销

plugins中加入以下配置

 // 开启Scop Hosting ,production 环境下默认开启
   new webpack.optimize.ModuleConcatenationPlugin(),

SplitChunksPlugin进行公共脚本分离

chunks说明

  • async 异步引入的库进行分离(默认)
  • initial 同步引入的库进行分离
  • all 所有引入的库进行分离(推荐)

详细配置如下:

module.exports = {

  optimization: {
    splitChunks: {
      chunks: 'async',
      minSize: 30000,  // 形成一个新代码块最小的体积,只有 >= minSize 的bundle会被拆分出来
      maxSize: 0, //拆分之前最大的数值,默认为0,即不做限制
      minChunks: 1, //引入次数,如果为2 那么一个资源最少被引用两次才可以被拆分出来
      maxAsyncRequests: 5,// 按需加载的最大并行请求数
      maxInitialRequests: 3, // 一个入口最大并行请求数
      automaticNameDelimiter: '~', // 文件名的连接符
      name: true,
      cacheGroups: {
        vendors: {
          test: /[\/]node_modules[\/]/,
          priority: -10
        },
        default: {
          minChunks: 2,
          priority: -20,
          reuseExistingChunk: true
        }
      }
    }
  }
};

html-webpack-externals-plugin优化打包速度

基础库分离

安装 html-webpack-externals-plugin

npm i html-webpack-externals-plugin -D

plugins中配置如下

  new HtmlWebpackExternalsPlugin({
      externals: [
        {
          module: 'react',
          entry: 'https://11.url.cn/now/lib/16.2.0/react.min.js',
          global: 'React'
        },
        {
          module: 'react-dom',
          entry: 'https://11.url.cn/now/lib/16.2.0/react-dom.min.js',
          global: 'ReactDOM'
        }
      ]
    }),

index.html 加入连接

<!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">
  <title>Hello Webpack</title>

</head>

<body>
  <div id="root"></div>
  <!-- react、react-dom提取配置-->
  <script type="text/javascript" src="https://11.url.cn/now/lib/16.2.0/react.min.js"></script>
  <script type="text/javascript" src="https://11.url.cn/now/lib/16.2.0/react-dom.min.js"></script>
</body>

</html>

clean-webpack-plugin(构建时清空dist目录)

安装插件

npm i clean-webpack-plugin -D

配置如下

var { CleanWebpackPlugin} = require('clean-webpack-plugin'); // 语法发生了改变

module.export = {
  plugins: [
      new CleanWebpackPlugin(), // 打包时先清空dist目录
  ]
}

px2rem-loader实现移动端适配

安装

npm i px2rem-loader -D
npm i lib-flexible -S

rule配置

     {
        test: /.less$/,
        use: [
          'style-loader',
          // MiniCssExtractPlugin.loader,
          'css-loader',
          'less-loader',
          {
            loader:'px2rem-loader',
            options : {
              remUnit: 75, // 1 rem = 75px
              remPrecesion: 8 // px转rem 小数点后面位数
            }
          }
        ]
      },

index.html中引入lib-flexible

postcss+autoprefixer 实现css3自动补全前缀

安装postcss-loader和autoprefixer

npm i postcss-loader autoprefixer -D

rule配置

    {
        test: /.less$/,
        use: [
          'style-loader',
          // MiniCssExtractPlugin.loader,
          'css-loader',
          'less-loader',
          {
            loader : 'postcss-loader',
            options : {
              plugins: ()=> {
                require('autoprefixer')({
                  browsers: ['last 2 version','>1%','ios 7']
                })
              }
            }
          }
        ]
      },

实现多页面打包

安装glob,实现目录页面遍历功能

npm i glob -D

配置如下

const glob = require('glob')

// 获取html-webpack-plugin参数的方法
var getHtmlConfig = function (name, title) {
  return {
      template: 'index.html', // 指定产出的模板
      filename: 'view/' + name + '.html', // 产出的文件名cls
      title: title,  // 可以给模板设置变量名,在html模板中调用 htmlWebpackPlugin.options.title 可以使用
      inject: true,
      hash: true,
      chunks: ['common', name]  // 在产出的HTML文件里引入哪些代码块
  };
};
// 获取多入口文件和htmlWebpackPlugin
setMap = () => {
  const entry = {};
  const htmlwebpackPlugin = []
  const entryFiles = glob.sync(path.join(__dirname,'../src/views/common/*/index.js'));

  Object.keys(entryFiles).map((index)=>{
    const entryFile = entryFiles[index];
    const match = entryFile.match(/common/(.*)/index.js/);
    const pageName = match && match[1];
    htmlwebpackPlugin.push(new HtmlWebpackPlugin(getHtmlConfig(pageName,pageName)));
    entry[pageName] = entryFile;
  
  })
  return {
    entry,
    htmlwebpackPlugin
  }
}
const {entry,htmlwebpackPlugin} = setMap();

module.exports = {
   entry: entry,
   output: {
    filename: '[name]_[chunkhash:8].js', // name相当于通配符 
    path: path.join(__dirname, 'dist')
  },
    plugins: [
  	].concat(htmlwebpackPlugin),
}

webpack实现SSR(服务器端)打包

服务端渲染 (SSR) 是什么?

渲染: HTML + CSS + JS + Data -> 渲染后的 HTML

服务端:

  • 所有模板等资源都存储在服务端
  • 内⽹机器拉取数据更快
  • ⼀个 HTML 返回所有数据

服务器端渲染&客户端渲染

总结:服务端渲染 (SSR) 的核⼼是减少请求

参考文档:www.freesion.com/article/419…