webpack常用配置总览(小结)


Posted in Javascript onNovember 18, 2019

简介

看《深入浅出webpack》总结一下常用的webpack的属性的含义并加了一些自己的链接,写在一个文件下更能有全局感受,更能理解各个属性中间的关系,重点要关注entry,output,resolve,module, plugins几部分

配置示例

这并不是一个拿来可用的配置,主要是为了更好理解常用的一些webpack属性的作用,所以每一行都有注释,放到一起,更能看到每一个属性在其中的作用

module.exports = {
  // __dirname值为所在文件的目录,context默认为执行webpack命令所在的目录
  context: path.resolve(__dirname, 'app'),
  // 必填项,编译入口,webpack启动会从配置文件开始解析,如下三种(还有一种动态加载entry的方式就是给entry传入一个函数,这个在项目比较大,页面很多的情况下可以优化编译时间)
  entry: './app/entry', // 只有一个入口,入口只有一个文件
  entry: ['./app/entry1', './app/entry2'], // 只有一个入口,入口有两个文件
    // 两个入口
  entry: {
    entry1: './app/entry1',
    entry2: './app/entry2'
  },
  // 输出文件配置
  output: {
    // 输出文件存放的目录,必须是string类型的绝对路径
    path: path.resolve(__dirname, 'dist'),
    // 输出文件的名称
    filename: 'bundle.js',
    filename: '[name].js', // 配置了多个入口entry是[name]的值会被入口的key值替换,此处输出文件会输出的文件名为entry1.js和entry2.js
    filename: [chunkhash].js, // 根据chunk的内容的Hash值生成文件的名称,其他只还有id,hash,hash和chunkhash后面可以使用:number来取值,默认为20位,比如[name]@[chunkhash:12].js,
    // 文件发布到线上的资源的URL前缀,一般用于描述js和css位置,举个例子,打包项目时会导出一些html,那么html里边注入的script和link的地址就是通过这里配置的
    publicPath: "https://cdn.example.com/assets/", // CDN(总是 HTTPS 协议)
    publicPath: "//cdn.example.com/assets/", // CDN (协议相同)
    publicPath: "/assets/", // 相对于服务(server-relative)
    publicPath: "assets/", // 相对于 HTML 页面
    publicPath: "../assets/", // 相对于 HTML 页面
    publicPath: "", // 相对于 HTML 页面(目录相同)
    // 当需要构建的项目可以被其他模块导入使用,会用到libraryTarget和library
    library: 'xxx', // 配置导出库的名称,但是和libraryTarget有关,如果是commonjs2默认导出这个名字就没啥用
    // 从webpack3.1.0开始,可以为每个target起不同的名称
    library: {
      root: "MyLibrary",
      amd: "my-library",
      commonjs: "my-common-library"
    },
    libraryTarget: 'umd', // 导出库的类型,枚举值: umd、commonjs2、commonjs,amd、this、var(默认)、assign、window、global、jsonp(区别查看补充2)
    // 需要单独导出的子模块,这样可以直接在引用的时候使用子模块,默认的时候是_entry_return_
    libraryExport: 'default', // __entry_return_.default
    libraryExport: 'MyModule', // __entry_return_.MyModule
    libraryExport: ['MyModule', 'MySubModule '], // 使用数组代表到指定模块的取值路径 __entry_return_.MyModule.MySubModule
    // 配置无入口的chunk在输出时的文件名称,但仅用于在运行过程中生成的Chunk在输出时的文件名称,这个应该一般和插件的导出有关,支持和filename一样的内置变量
    chunkFilename: '[id].js',
    // 是否包含文件依赖相关的注释信息,不懂?请看补充3,在mode为development的是默认为true
    pathinfo: true,
    // JSONP异步加载chunk,或者拼接多个初始chunk(CommonsChunkPlugin,AggressiveSplittingPlugin)
    jsonpFunction: 'myWebpackJsonp',
    // 此选项会向应盘写入一个输出文件,只在devtool启动了sourceMap选项时采用,默认为`[file].map`,除了和filename一样外还可以使用[file]
    sourceMapFilename: '[file].map',
    // 浏览器开发者工具里显示的源码模块名称,此选项仅在 「devtool 使用了需要模块名称的选项」时使用,使用source-map调试,关联模块鼠标移动到上面的时候显示的地址(截不到图啊,醉了),默认这个值是有的,一般不需要关心
    devtoolModuleFilenameTemplate: 'testtest://[resource-path]'
  },
  // 配置模块相关
  module: {
    rules: [ // 配置loaders
      {
        test: /\.jsx?$/, // 匹配规则,匹配文件使用,一般使用正则表达值
        include: [path.resolve(__dirname, 'app')], // 只会命中这个目录文件
        exclude: [path.resolve(__diranme, 'app/demo-files')], // 命中的时候排除的目录
        use: [ // 使用的loader,每一项为一个loader,从该数组的最后一个往前执行
          'style-loader', // loader的名称,这样则是使用默认配置,可以在后面加!配置属性,也可以用下面方式
          {
            loader: 'css-loader', // loader的名称
            options: {} // loader接受的参数
          }
        ],
        noParse: [ // 不用解析和处理的模块 RegExp | [RegExp] | function(从 webpack 3.0.0 开始)
          /jquery|lodash/
        ]
      }
    ]
  },
  // 配置插件,关于和loader区别见补充4
  plugins: [
   // 压缩js的plugin
   new webpack.optimize.UglifyJsPlugin({
    compress: {
     warnings: false,
     drop_console: false,
    }
   }),
  ],
  // 解析文件引用的模块的配置
  resolve: {
    // 模块的根目录,默认从node_modules开始找
    modules: [
      'node_modules',
      'browser_modules'
    ],
    // 模块的后缀名,我们引入模块有时候不写扩展名,自动补充扩展名的顺序如下
    extensions: ['.js', '.json', '.jsx', '.css'],
    // 模块解析时候的别名
    alias: {
      // 那么导入模块时则可以写import myComponent from '$component/myComponent';
      $component: './src/component',
      // 末尾加$精确匹配
      xyz$: path.resolve(__dirname, 'path/to/file.js')
    },
    // 此选项决定优先使用package.json配置哪份导出文件,详见补充5
    mainFields: ['jsnext:main', 'browser', 'main'],
    // 是否强制导入语句写明后缀
    enforceExtension: false,
    // 是否将符号链接(symlink)解析到它们的符号链接位置(symlink location)
    symlinks: true,
  },
  // 选择一种 source map 格式来增强调试过程。不同的值会明显影响到构建(build)和重新构建(rebuild)的速度。
  devtool: 'source-map',
  // 配置输出代码的运行环境,可以为async-node,electron-main,electron-renderer,node,node-webkit,web(默认),webworker
  target: 'web',
  externals: { // 使用来自于js运行环境提供的全局变量
    jquery: 'jQuery'
  },
  // 控制台输出日志控制
  stats: {
    assets: true, // 添加资源信息
    colors: true, // 控制台日志信息是否有颜色
    errors: true, // 添加错误信息
    errorDetails: true, // 添加错误的详细信息(就像解析日志一样)
    hash: true, // 添加 compilation 的哈希值
  },
  devServer: { // 本地开发服务相关配置
    proxy: { // 代理到后端服务接口
      '/api': 'http://localhost:3000'
    },
    contentBase: path.join(__dirname, 'public'), // 配置devserver http服务器文件的根目录
    compress: true, // 是否开启gzip压缩
    hot: true, // 是否开启模块热交换功能
    https: false, // 是否开启https模式
    historyApiFallback: true, // 是否开发HTML5 History API网页,不太理解TODO
  },
  profile: true, // 是否捕捉webpack构建的性能信息,用于分析是什么原因导致的构建性能不佳
  cache: false, // 缓存生成的 webpack 模块和 chunk,来改善构建速度。缓存默认在观察模式(watch mode)启用。
  cache: {
    // 如果传递一个对象,webpack 将使用这个对象进行缓存。保持对此对象的引用,将可以在 compiler 调用之间共享同一缓存:
    cache: SharedCache // let SharedCache = {}
  },
  watch: true, // 是否启用监听模式
  watchOptions: { // 监听模式选项
    ignored: /node_modules/, // 不监听的文件或文件夹,支持正则匹配,默认为空
    aggregateTimeout: 300, 监听到变化后,300ms再执行动作,节流,防止文件更新频率太快导致重新编译频率太快
    poll: 1000 // 检测文件是否变化,间隔时间
  },
  // 输出文件的性能检查配置
  perfomance: {
    hints: 'warning', // 有性能问题时输出警告
    hints: 'error', // 有性能问题时输出错误
    hints: false, // 关闭性能检查
    maxAssetSize: 200000, // 最大文件大小,单位bytes
    maxEntrypointSize: 400000, // 最大入口文件的大小,单位bytes
    // 此属性允许 webpack 控制用于计算性能提示的文件。
    assetFilter: function(assetFilename) {
      return assetFilename.endsWith('.css') || assetFilename.endsWith('.js');
    }
  }
}

补充

补充1.chunkname是什么

就是打包后代码块的名字

补充2.补充不同的库导出方式的区别

var

var MyLibrary = _entry_return_;
// 在一个单独的 script……
MyLibrary.doSomething();

assign 暴露到全局变量中,不要用this 分配给this,感觉会放在全局的this上,官网说取决于你

window 将模块放在window上

window["MyLibrary"] = _entry_return_;

window.MyLibrary.doSomething();

global 调动方式使用global['myLibrary']

commonjs

commonjs2

说一下这两种区别,其实这说到了exports和module.exports的区别,exports是module.exports的一个引用

module.exports = {};
  exports = module.exports;
  exports['aaaa'] = 1; // 这样是可以的,在module.exports上加了一个属性
  exports = 2; // 会导致exports脱离了对module.exports的引用
  modules.exports = 2 // 这样 exports的至最后就是2

那么其实commonjs的规定就是使用exports进行导出,而我们经常使用module.exports导出,webpack此处的方式其实就是选择到底是用exports导出还是module.exports导出,区别在于
如果选择commonjs

// webpack输出为
  exports['LibraryName'] = _entry_return_;
  // 使用库的方法为
  require('library-name-in-npm')['LibraryName'].doSomething();
  // 原因其实就是这么导出最后其实是 
  // modules.exports = { [LibraryName]: _entry_return_ }

如果选择commonjs2

// webpack输出为
  module.exports = _entry_return_;
  // 使用库的方法为
  require('library-name-in-npm').doSomething();

amd

// webpack输出
define("MyLibrary", [], function() {
  return _entry_return_; // 此模块返回值,是入口 chunk 返回的值
});
// 使用
require(['MyLibrary'], function(MyLibrary) {
  // 使用 library 做一些事……
});

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_; // 此模块返回值,是入口 chunk 返回的值
 });

jsonp 你的 library 的依赖将由 externals 配置定义。

MyLibrary(_entry_return_);

补充3.pathinfo到底是哪些玩意

webpack常用配置总览(小结)

补充4.plugins和loader什么区别?

我的理解是

loader使用来识别出特定文件,并转换文件内容,方便webpack使用,比如css文件要解析,需要将其转换成js代码放到js中,才能被后续处理(当然可以省略),然后加入最后输出的js当中
plugin是帮助webpack做一些额外的工作,补充一些webpack本身没有实现的功能,有种打补丁的意思,更专注于打包、编译、输出js文件等操作以及在某些阶段要额外做的一些操作,比如html插件将其链接地址插入html

补充5. 关于mainFields的解释

有一些第三方模块会针对不同的环境提供几份代码,例如分别提供了ES5和ES6两份代码,在package.json中代码如下:

{
  "jsnext:main": "es/index.js", // 采用es6的入口文件
  "main": "lib/index.js", // 采用es5语法的代码入口文件
}

那么webpack会根据mainFields数组里的顺序,逐步找到文件

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
Jquery中获取iframe的代码
Jan 11 Javascript
一个背景云变换js特效 鼠标移动背景云变化
Dec 28 Javascript
结合JQ1.9通过js正则判断各种浏览器版本的方法
Dec 30 Javascript
js 日期比较相关天数代码
Apr 02 Javascript
javascript学习指南之回调问题
Apr 23 Javascript
jQuery对checkbox 复选框的全选全不选反选的操作
Aug 09 Javascript
AngularJS入门教程之数据绑定原理详解
Nov 02 Javascript
基于jQuery的select下拉框选择触发事件实例分析
Nov 18 Javascript
微信小程序倒计时功能实现代码
Nov 09 Javascript
Vue自定义指令上报Google Analytics事件统计的方法
Feb 25 Javascript
vue使用Proxy实现双向绑定的方法示例
Mar 20 Javascript
实例分析JS中的相等性判断===、 ==和Object.is()
Nov 17 Javascript
vue使用一些外部插件及样式的配置代码
Nov 18 #Javascript
重置Redux的状态数据的方法实现
Nov 18 #Javascript
JavaScript数值类型知识汇总
Nov 17 #Javascript
实例分析JS中的相等性判断===、 ==和Object.is()
Nov 17 #Javascript
AngularJS动态生成select下拉框的方法实例
Nov 17 #Javascript
24行JavaScript代码实现Redux的方法实例
Nov 17 #Javascript
JavaScript如何处理移动端拍摄图片旋转问题
Nov 16 #Javascript
You might like
深入理解:XML与对象的序列化与反序列化
2013/06/08 PHP
浅析php中json_encode()和json_decode()
2014/05/25 PHP
PHP贪婪算法解决0-1背包问题实例分析
2015/03/23 PHP
PHP中把有符号整型转换为无符号整型方法
2015/05/27 PHP
在Mac OS上自行编译安装Apache服务器和PHP解释器
2015/12/24 PHP
PHP扩展迁移为PHP7扩展兼容性问题记录
2016/02/15 PHP
php 中奖概率算法实现代码
2017/01/25 PHP
修改jQuery.Autocomplete插件 支持中文输入法 避免TAB、ENTER键失效、导致表单提交
2009/10/11 Javascript
javascript 学习笔记(六)浏览器类型及版本信息检测代码
2011/04/08 Javascript
Js判断参数(String,Array,Object)是否为undefined或者值为空
2013/11/04 Javascript
Node.js编程中客户端Session的使用详解
2015/06/23 Javascript
JavaScript实现同时调用多个函数的方法
2015/11/09 Javascript
jQuery的ajax下载blob文件
2016/07/21 Javascript
微信小程序开发(一) 微信登录流程详解
2017/01/11 Javascript
利用Javascript获取选择文本所在的句子详解
2017/12/03 Javascript
vue使用自定义icon图标的方法
2018/05/14 Javascript
node静态服务器实现静态读取文件或文件夹
2019/12/03 Javascript
[49:40]2018DOTA2亚洲邀请赛小组赛 A组加赛 TNC vs Newbee
2018/04/03 DOTA
在Python中操作文件之read()方法的使用教程
2015/05/24 Python
简介Python设计模式中的代理模式与模板方法模式编程
2016/02/02 Python
python DataFrame获取行数、列数、索引及第几行第几列的值方法
2018/04/08 Python
Python数据结构与算法(几种排序)小结
2019/06/22 Python
Python自定义一个异常类的方法
2019/06/27 Python
使用pandas读取文件的实现
2019/07/31 Python
在Python中使用filter去除列表中值为假及空字符串的例子
2019/11/18 Python
Python基础之字典常见操作经典实例详解
2020/02/26 Python
英国天然有机美容护肤品:Neal’s Yard Remedies
2018/05/05 全球购物
澳大利亚墨尔本的在线时装店:LORETA
2018/09/14 全球购物
美国杰西潘尼官网:JCPenney
2019/06/12 全球购物
Java的类可以定义为Protected或者Private得吗
2015/09/25 面试题
人力资源总监工作说明
2014/03/03 职场文书
关爱留守儿童倡议书
2014/04/15 职场文书
2016年公司新年寄语
2015/08/17 职场文书
基于tensorflow权重文件的解读
2021/05/26 Python
使用Oracle命令进行数据库备份与还原
2021/12/06 Oracle
十大最强奥特曼武器:怪兽战斗仪在榜,第五奥特之父只使用过一次
2022/03/18 日漫