在前面两篇博客中,主要讲了webpack的使用和webpack的核心概念,他们都是非常重要的,在这篇博客中,讲主要讨论webpack配置相关问题。

  参考文章:https://webpack.js.org/configuration/

  对于配置文件中不懂的地方都可以在上面的文章中找到最精确的文档来查看学习。

第一部分

  可能你已经注意到了几乎没有两个configuration是相同的,这是因为webpack的配置文件就是一个导出一个对象的js文件。这个对象将会基于自身的属性被处理。

  因为这是nodejs中的Commonjs标准,所以我们可以这样做:

  • 通过require()引入其他的文件。
  • 通过require()使用npm中的一些功能。
  • 使用js的控制流表达式如 ?: 操作符。
  • 对于经常使用的值使用常量或者变量来表示。

  另外,下面的这些事不推荐的:

  • 当使用webpack CLI时,使用CLI参数。
  • 导出不确定的值。
  • 写了很长的配置(而不是将配置文件分割为多份不同功能的配置文件)。 比如我们使用vue-cli时就会发现webpack的配置文件有4个之多,这就是为了防止一个配置文件过大而冗杂。

  下面就是一个最简单的配置文件:

var path = require('path');

module.exports = {
entry: './foo.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'foo.bundle.js'
}
};

  

下面也是一个配置文件,它是包含多对象的:

var path = require('path');
var webpack = require('webpack');
var webpackMerge = require('webpack-merge'); var baseConfig = {
target: 'async-node',
entry: {
entry: './entry.js'
},
output: {
path: path.resolve(__dirname, 'dist'),
filename: '[name].js'
},
plugins: [
new webpack.optimize.CommonsChunkPlugin({
name: 'inline',
filename: 'inline.js',
minChunks: Infinity
}),
new webpack.optimize.AggressiveSplittingPlugin({
minSize: ,
maxSize:
}),
]
}; let targets = ['web', 'webworker', 'node', 'async-node', 'node-webkit', 'electron-main'].map((target) => {
let base = webpackMerge(baseConfig, {
target: target,
output: {
path: path.resolve(__dirname, 'dist/' + target),
filename: '[name].' + target + '.js'
}
});
return base;
}); module.exports = targets;

对于这个配置文件,有下面几点需要说明:

  1. 对于配置文件,我们有很多种组织方式来配置, 最重要的是坚持一致性并且保证你的团队都可以理解并维护他们。
  2. 对于多个对象,我们常用的就是webpackMerge函数,这个函数可以将多个对象merge为一个对象。
  3. 这里最后导出的是一个targets数组,其中的每一个元素都是合并之后的对象。

第二部分

  不难发现,之前我们在写配置文件时往往会用到node的内置模块---path模块。通过传入全局变量__dirname来使用。 这样可以防止出现文件的路径错误问题,因为不同的操作系统和对于相对路径/绝对路径的支持问题。   

const path = require('path');

module.exports = {
// click on the name of the option to get to the detailed documentation
// click on the items with arrows to show more examples / advanced options entry: "./app/entry", // string | object | array
// Here the application starts executing
// and webpack starts bundling output: {
// options related to how webpack emits results path: path.resolve(__dirname, "dist"), // string
// the target directory for all output files
// must be an absolute path (use the Node.js path module) filename: "bundle.js", // string
// the filename template for entry chunks publicPath: "/assets/", // string
// the url to the output directory resolved relative to the HTML page library: "MyLibrary", // string,
// the name of the exported library libraryTarget: "umd", // universal module definition
// the type of the exported library /* Advanced output configuration (click to show) */
}, module: {
// configuration regarding modules rules: [
// rules for modules (configure loaders, parser options, etc.) {
test: /\.jsx?$/,
include: [
path.resolve(__dirname, "app")
],
exclude: [
path.resolve(__dirname, "app/demo-files")
],
// these are matching conditions, each accepting a regular expression or string
// test and include have the same behavior, both must be matched
// exclude must not be matched (takes preferrence over test and include)
// Best practices:
// - Use RegExp only in test and for filename matching
// - Use arrays of absolute paths in include and exclude
// - Try to avoid exclude and prefer include issuer: { test, include, exclude },
// conditions for the issuer (the origin of the import) enforce: "pre",
enforce: "post",
// flags to apply these rules, even if they are overridden (advanced option) loader: "babel-loader",
// the loader which should be applied, it'll be resolved relative to the context
// -loader suffix is no longer optional in webpack2 for clarity reasons
// see webpack 1 upgrade guide options: {
presets: ["es2015"]
},
// options for the loader
}, {
test: "\.html$", use: [
// apply multiple loaders and options
"htmllint-loader",
{
loader: "html-loader",
options: {
/* ... */
}
}
]
}, { oneOf: [ /* rules */ ] },
// only use one of these nested rules { rules: [ /* rules */ ] },
// use all of these nested rules (combine with conditions to be useful) { resource: { and: [ /* conditions */ ] } },
// matches only if all conditions are matched { resource: { or: [ /* conditions */ ] } },
{ resource: [ /* conditions */ ] },
// matches if any condition is matched (default for arrays) { resource: { not: /* condition */ } }
// matches if the condition is not matched
], /* Advanced module configuration (click to show) */
}, resolve: {
// options for resolving module requests
// (does not apply to resolving to loaders) modules: [
"node_modules",
path.resolve(__dirname, "app")
],
// directories where to look for modules extensions: [".js", ".json", ".jsx", ".css"],
// extensions that are used alias: {
// a list of module name aliases "module": "new-module",
// alias "module" -> "new-module" and "module/path/file" -> "new-module/path/file" "only-module$": "new-module",
// alias "only-module" -> "new-module", but not "module/path/file" -> "new-module/path/file" "module": path.resolve(__dirname, "app/third/module.js"),
// alias "module" -> "./app/third/module.js" and "module/file" results in error
// modules aliases are imported relative to the current context
},
/* alternative alias syntax (click to show) */ /* Advanced resolve configuration (click to show) */
}, performance: {
hints: "warning", // enum
maxAssetSize: , // int (in bytes),
maxEntrypointSize: , // int (in bytes)
assetFilter: function(assetFilename) {
// Function predicate that provides asset filenames
return assetFilename.endsWith('.css') || assetFilename.endsWith('.js');
}
}, devtool: "source-map", // enum
// enhance debugging by adding meta info for the browser devtools
// source-map most detailed at the expense of build speed. context: __dirname, // string (absolute path!)
// the home directory for webpack
// the entry and module.rules.loader option
// is resolved relative to this directory target: "web", // enum
// the environment in which the bundle should run
// changes chunk loading behavior and available modules externals: ["react", /^@angular\//],
// Don't follow/bundle these modules, but request them at runtime from the environment stats: "errors-only",
// lets you precisely control what bundle information gets displayed devServer: {
proxy: { // proxy URLs to backend development server
'/api': 'http://localhost:3000'
},
contentBase: path.join(__dirname, 'public'), // boolean | string | array, static file location
compress: true, // enable gzip compression
historyApiFallback: true, // true for index.html upon 404, object for multiple paths
hot: true, // hot module replacement. Depends on HotModuleReplacementPlugin
https: false, // true for self-signed, object for cert authority
noInfo: true, // only errors & warns on hot reload
// ...
}, plugins: [
// ...
],
// list of additional plugins /* Advanced configuration (click to show) */
}

在上面的配置文件中我们应该可以找到大部分遇到的问题了。

配置语言

  webpack允许你使用任何语言来写配置文件。配置文件支持的语言我们可以在node-interpret中看到。也就是说,webpack在node-interpret的支持下将会根据你的选择语言来运行你的配置文件。

  比如,你可以使用coffeescript,如下所示:

HtmlWebpackPlugin = require('html-webpack-plugin')
webpack = require('webpack')
path = require('path')
config =
entry: './path/to/my/entry/file.js'
output:
path: path.resolve(__dirname, 'dist')
filename: 'my-first-webpack.bundle.js'
module: rules: [ {
test: /\.(js|jsx)$/
use: 'babel-loader'
} ]
plugins: [
new (webpack.optimize.UglifyJsPlugin)
new HtmlWebpackPlugin(template: './src/index.html')
]
module.exports = config

  这样的配置文件也是可以正常执行的。

配置类型

  对于一个配置文件,我们除了可以导出一个配置对象,还有很多其他的方式来满足满足我们的需求。  

为使用 --env 导出一个函数

  最终你将会发现这样一个需求:在你的webpack.config.js中消除developmentproduction builds之间的歧义。你至少有两个选择:

  不是导出一个配置对象,而是导出一个返回的函数,这个函数可以接受环境参数作为变量。当你运行webpack时,你可以指定构建环境的关键词通过 --env, 比如使用 --env.production 或者是 --env.platform=web。 如下所示;

-module.exports = {
+module.exports = function(env) {
+ return {
plugins: [
new webpack.optimize.UglifyJsPlugin({
+ compress: env.production // compress only in production build
})
]
+ };
};

  其中的+标识新添加的代码,其中的-标识不需要、删除的代码。

导出一个promise

  webpack将会运行通过配置文件导出的函数并且等待一个promise被返回,当你需要异步的加载配置变量时这是非常方便的。

module.exports = () => {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve({
entry: './app.js',
/* ... */
})
}, )
})
}

导出多个配置文件

  不是导出一个配置对象或函数,你可以导出多个配置文件。 当运行webpack时,所有的配置文件都会被建立, 比如,在创建一个库时这是非常有用的

module.exports = [{
output: {
filename: './dist-amd.js',
libraryTarget: 'amd'
},
entry: './app.js',
}, {
output: {
filename: './dist-commonjs.js',
libraryTarget: 'commonjs'
},
entry: './app.js',
}]

//webpack.js.org/guides/production-build/

最新文章

  1. BZOJ 1041: [HAOI2008]圆上的整点
  2. Yii2.0数据库操作增删改查详解
  3. 3. Swift 数组|字典|集合
  4. Win7_64位使用Mysql Odbc
  5. @font-face usage
  6. String,StringBuffer与StringBuilder的差别??
  7. win32 sdk绘制ListBox控件
  8. 通用JSONHelp 的通用的封装
  9. eclipse环境下基于已构建struts2项目整合spring+hibernate
  10. A1134. Vertex Cover
  11. 顶级项目孵化的故事系列——Kylin的心路历程【转】
  12. Luogu P2002 消息扩散&&P1262 间谍网络
  13. binlog和redo log日志提交
  14. mysql show master status为空值
  15. Python数据分析--Pandas知识点(二)
  16. 如何在Eclipse下安装SVN插件——subclipse
  17. 比较windows phone程序启动和android程序启动原理
  18. vs启动项目提示Web 服务器被配置为不列出此目录的内容。
  19. BZOJ 1176 Mokia CDQ分治+树状数组
  20. java 单例的实现及多线程下的安全

热门文章

  1. 《Head First Servlets & JSP》-6-会话管理-listener etc. demo
  2. 跑实验配环境(tensorflow)
  3. Dubbo项目入门
  4. Grideview总结
  5. WPARAM和LPARAM的含义
  6. EIP权限工作流升级说明-2019/3/5
  7. SnackBar使用
  8. loj #2037. 「SHOI2015」脑洞治疗仪
  9. socketserver,threading
  10. cenos云服务器搭建虚拟主机