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 相关文章推荐
ASP.NET jQuery 实例2 (表单中使用回车在TextBox之间向下移动)
Jan 13 Javascript
Javascript的严格模式strict mode详细介绍
Jun 06 Javascript
浅谈node.js中async异步编程
Oct 22 Javascript
JQuery 传送中文乱码问题的简单解决办法
May 24 Javascript
深入浅析JS是按值传递还是按引用传递(推荐)
Sep 18 Javascript
Javascript typeof与instanceof的区别
Oct 18 Javascript
JavaScript中undefined和null的区别
May 03 Javascript
jQuery选择器之表单元素选择器详解
Sep 19 jQuery
Vue异步加载about组件
Oct 31 Javascript
Vue Prop属性功能与用法实例详解
Feb 23 Javascript
vue + typescript + video.js实现 流媒体播放 视频监控功能
Jul 07 Javascript
利用React高阶组件实现一个面包屑导航的示例
Aug 23 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
DC这些乐高系列动画电影你看过几部?
2020/04/09 欧美动漫
《魔兽争霸3》重制版究竟重制了什么?玩家:这么糊弄真的好吗?
2020/05/04 魔兽争霸
利用yahoo汇率接口实现实时汇率转换示例 汇率转换器
2014/01/14 PHP
thinkphp3.2.2前后台公用类架构问题分析
2014/11/25 PHP
php实现微信扫码自动登陆与注册功能
2016/09/22 PHP
Laravel用户授权系统的使用方法示例
2018/09/16 PHP
javascript Xml增删改查(IE下)操作实现代码
2009/01/30 Javascript
jquery 将disabled的元素置为enabled的三种方法
2009/07/25 Javascript
JavaScript 浏览器验证代码(来自discuz)
2010/07/17 Javascript
JQuery select控件的相关操作实现代码
2012/09/14 Javascript
jQuery插件开发全解析
2012/10/10 Javascript
用jquery生成二级菜单的实例代码
2013/06/24 Javascript
jquery原创弹出层折叠效果点击折叠弹出一个层
2014/03/12 Javascript
加载列表时jquery获取ul中第一个li的属性
2014/11/02 Javascript
jQuery左右滚动支持图片放大缩略图图片轮播代码分享
2015/08/26 Javascript
Javascript将数字转化成为货币格式字符串
2016/06/22 Javascript
基于jQuery实现火焰灯效果导航菜单
2017/01/04 Javascript
bootstrap中添加额外的图标实例代码
2017/02/15 Javascript
基于打包工具Webpack进行项目开发实例
2018/05/29 Javascript
详解Vue webapp项目通过HBulider打包原生APP
2018/06/29 Javascript
jQuery扩展方法实现Form表单与Json互相转换的实例代码
2018/09/05 jQuery
使用 Vue cli 3.0 构建自定义组件库的方法
2019/04/30 Javascript
在Python中操作字符串之startswith()方法的使用
2015/05/20 Python
python之cv2与图像的载入、显示和保存实例
2018/12/05 Python
LookFantastic丹麦:英国美容护肤精品在线商城
2016/08/18 全球购物
欧洲著名的珠宝和手表网上商城:uhrcenter
2017/04/10 全球购物
J2ee常用的设计模式?说明工厂模式
2015/05/21 面试题
工商管理专业学生的自我评价
2013/10/01 职场文书
测试工程师岗位职责
2013/11/28 职场文书
人力资源部门的主要职能
2014/02/22 职场文书
中介公司区域经理岗位职责范本
2014/03/02 职场文书
婚礼主持词开场白
2014/03/13 职场文书
乡镇保密工作责任书
2014/07/28 职场文书
创建绿色学校先进个人材料
2014/08/20 职场文书
咖啡店创业计划书范文
2014/09/15 职场文书
Vue-Element-Admin集成自己的接口实现登录跳转
2021/06/23 Vue.js