1. 缩小范围 #

1.1 extensions #

指定extension之后可以不用在require或是import的时候加文件扩展名,会依次尝试添加扩展名进行匹配

resolve: {
  extensions: [".js",".jsx",".json",".css"]
},

1.2 alias #

配置别名可以加快webpack查找模块的速度

const bootstrap = path.resolve(__dirname,'node_modules/_bootstrap@3.3.7@bootstrap/dist/css/bootstrap.css');
resolve: {
+    alias:{
+        "bootstrap":bootstrap
+    }
},

1.3 modules #

1.4 mainFields #

默认情况下package.json 文件则按照文件中 main 字段的文件名来查找文件

resolve: {
  // 配置 target === "web" 或者 target === "webworker" 时 mainFields 默认值是:
  mainFields: ['browser', 'module', 'main'],
  // target 的值为其他时,mainFields 默认值为:
  mainFields: ["module", "main"],
}

1.5 mainFiles #

当目录下没有 package.json 文件时,我们说会默认使用目录下的 index.js 这个文件,其实这个也是可以配置的

resolve: {
  mainFiles: ['index'], // 你可以添加其他默认使用的文件名
},

1.6 resolveLoader #

resolve.resolveLoader用于配置解析 loader 时的 resolve 配置,默认的配置:

module.exports = {
  resolveLoader: {
    modules: [ 'node_modules' ],
    extensions: [ '.js', '.json' ],
    mainFields: [ 'loader', 'main' ]
  }
};

2. noParse #

3. DefinePlugin #

DefinePlugin创建一些在编译时可以配置的全局常量

let webpack = require('webpack');
new webpack.DefinePlugin({
    PRODUCTION: JSON.stringify(true),
    VERSION: "1",
    EXPRESSION: "1+2",
    COPYRIGHT: {
        AUTHOR: JSON.stringify("珠峰培训")
    }
})
console.log(PRODUCTION);
console.log(VERSION);
console.log(EXPRESSION);
console.log(COPYRIGHT);

4. IgnorePlugin #

IgnorePlugin用于忽略某些特定的模块,让 webpack 不把这些指定的模块打包进去

4.1 src/index.js #

import moment from  'moment';
import 'moment/locale/zh-cn'
console.log(moment().format('MMMM Do YYYY, h:mm:ss a'));

4.2 webpack.config.js #

import moment from  'moment';
console.log(moment);
      new webpack.IgnorePlugin({
          //A RegExp to test the context (directory) against.
          contextRegExp: /moment$/,
          //A RegExp to test the request against.
          resourceRegExp: /^\.\/locale/
      new MiniCSSExtractPlugin({
          filename:'[name].css'
      })
      /*  new webpack.IgnorePlugin( {
         //A filter function for resource and context.
         checkResource: (resource, context) => {
             if(/moment$/.test(context)){
                 if(/^\.\/locale/.test(resource)){
                     if(!(/zh-cn/.test(resource))){
                         return true;
                     }
                 }
             }
             return false;
         } 
     })*/

7. 日志优化 #

预设 替代 描述
errors-only none 只在错误时输出
minimal none 发生错误和新的编译时输出
none false 没有输出
normal true 标准输出
verbose none 全部输出

7.1 friendly-errors-webpack-plugin #

npm i friendly-errors-webpack-plugin
+ stats:'verbose',
  plugins:[
+   new FriendlyErrorsWebpackPlugin()
  ]

编译完成后可以通过echo $?获取错误码,0为成功,非0为失败

8. 日志输出 #

  "scripts": {
    "build": "webpack",
+    "build:stats":"webpack --json > stats.json",
    "dev": "webpack-dev-server --open"
  },
const webpack = require('webpack');
const config = require('./webpack.config.js');
webpack(config,(err,stats)=>{
  if(err){
    console.log(err);
  }
  if(stats.hasErrors()){
    return console.error(stats.toString("errors-only"));
  }
  console.log(stats);
});

9.费时分析 #

const SpeedMeasureWebpackPlugin = require('speed-measure-webpack-plugin');
const smw = new SpeedMeasureWebpackPlugin();
module.exports =smw.wrap({
});

10.webpack-bundle-analyzer #

cnpm i webpack-bundle-analyzer -D
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
module.exports={
  plugins: [
    new BundleAnalyzerPlugin()  // 使用默认配置
    // 默认配置的具体配置项
    // new BundleAnalyzerPlugin({
    //   analyzerMode: 'server',
    //   analyzerHost: '127.0.0.1',
    //   analyzerPort: '8888',
    //   reportFilename: 'report.html',
    //   defaultSizes: 'parsed',
    //   openAnalyzer: true,
    //   generateStatsFile: false,
    //   statsFilename: 'stats.json',
    //   statsOptions: null,
    //   excludeAssets: null,
    //   logLevel: info
    // })
  ]
}
{
 "scripts": {
    "dev": "webpack --config webpack.dev.js --progress"
  }
}

webpack.config.js

const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
module.exports={
  plugins: [
    new BundleAnalyzerPlugin({
      analyzerMode: 'disabled', // 不启动展示打包报告的http服务器
      generateStatsFile: true, // 是否生成stats.json文件
    }),
  ]
}
{
 "scripts": {
    "generateAnalyzFile": "webpack --profile --json > stats.json", // 生成分析文件
    "analyz": "webpack-bundle-analyzer --port 8888 ./dist/stats.json" // 启动展示打包报告的http服务器
  }
}
npm run generateAnalyzFile
npm run analyz

11. libraryTarget 和 library #

libraryTarget 使用者的引入方式 使用者提供给被使用者的模块的方式
var 只能以script标签的形式引入我们的库 只能以全局变量的形式提供这些被依赖的模块
commonjs 只能按照commonjs的规范引入我们的库 被依赖模块需要按照commonjs规范引入
commonjs2 只能按照commonjs2的规范引入我们的库 被依赖模块需要按照commonjs2规范引入
amd 只能按amd规范引入 被依赖的模块需要按照amd规范引入
this
window
global
umd 可以用script、commonjs、amd引入 按对应的方式引入

10.1 var (默认) #

编写的库将通过var被赋值给通过library指定名称的变量。

10.1.1 webpack.config.js #

{
  output: {
        path: path.resolve("build"),
        filename: "[name].js",
+       library:'calculator',
+       libraryTarget:'var'
  }
}

10.1.2 index.js #

module.exports =  {
    add(a,b) {
        return a+b;
    }
}

10.1.3 bundle.js #

var calculator=(function (modules) {}({})

10.1.4 index.html #

    <script src="bundle.js"></script>
    <script>
        let ret = calculator.add(1,2);
        console.log(ret);
    </script>

10.2 commonjs #

10.2.1 导出方式 #

exports["calculator"] = (function (modules) {}({})

10.2.2 使用方式 #

let main = require('./main');
console.log(main.calculator.add(1,2));
require('npm-name')['calculator'].add(1,2);

npm-name是指模块发布到 Npm 代码仓库时的名称

10.3 commonjs2 #

10.3.2 使用方式 #

require('npm-name').add();

在 output.libraryTarget 为 commonjs2 时,配置 output.library 将没有意义。

10.4 this #

10.4.2 使用方式 #

this.calculator.add();

10.5 window #

10.5.2 使用方式 #

window.calculator.add();

10.6 global #

10.6.2 使用方式 #

global.calculator.add();

10.7 umd #

(function webpackUniversalModuleDefinition(root, factory) {
  if(typeof exports === 'object' && typeof module === 'object')
    module.exports = factory();
  else if(typeof define === 'function' && define.amd)
    define([], factory);
  else if(typeof exports === 'object')
    exports['MyLibrary'] = factory();
  else
    root['MyLibrary'] = factory();
})(typeof self !== 'undefined' ? self : this, function() {
  return _entry_return_;
});