devserver配置_webpack 常用配置总览

本文原载于 SegmentFault 社区

作者:Jackwang


简介

看《深入浅出 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的pluginnew 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 到底是哪些玩意

478354fe12e194288b98bf268c4e1cb8.png

补充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 数组里的顺序,逐步找到文件。 - END - cbde9902dae7c38fdcc2024c37ed974f.png
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值