深入学习webpack(三)
在前面两篇博客中,主要讲了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;
对于这个配置文件,有下面几点需要说明:
- 对于配置文件,我们有很多种组织方式来配置, 最重要的是坚持一致性并且保证你的团队都可以理解并维护他们。
- 对于多个对象,我们常用的就是webpackMerge函数,这个函数可以将多个对象merge为一个对象。
- 这里最后导出的是一个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中消除development和production 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/
深入学习webpack(三)的更多相关文章
- 深入学习webpack(二)
深入学习webpack(二) 在深入学习webpack(一)中,我通过一个例子介绍了webpack的基本使用方法,下面将更为系统的学习webpack的基本概念,对于一门技术的掌握我认为系统化还是很重要 ...
- Oracle学习笔记三 SQL命令
SQL简介 SQL 支持下列类别的命令: 1.数据定义语言(DDL) 2.数据操纵语言(DML) 3.事务控制语言(TCL) 4.数据控制语言(DCL)
- 从零开始学习jQuery (三) 管理jQuery包装集
本系列文章导航 从零开始学习jQuery (三) 管理jQuery包装集 一.摘要 在使用jQuery选择器获取到jQuery包装集后, 我们需要对其进行操作. 本章首先讲解如何动态的创建元素, 接着 ...
- 前端学习 第三弹: JavaScript语言的特性与发展
前端学习 第三弹: JavaScript语言的特性与发展 javascript的缺点 1.没有命名空间,没有多文件的规范,同名函数相互覆盖 导致js的模块化很差 2.标准库很小 3.null和unde ...
- Android Animation学习(三) ApiDemos解析:XML动画文件的使用
Android Animation学习(三) ApiDemos解析:XML动画文件的使用 可以用XML文件来定义Animation. 文件必须有一个唯一的根节点: <set>, <o ...
- 三、Android学习第三天——Activity的布局初步介绍(转)
(转自:http://wenku.baidu.com/view/af39b3164431b90d6c85c72f.html) 三.Android学习第三天——Activity的布局初步介绍 今天总结下 ...
- JavaWeb学习总结(三)——Tomcat服务器学习和使用(二) 包含https 非对称秘钥 NB
JavaWeb学习总结(三)--Tomcat服务器学习和使用(二) 一.打包JavaWeb应用 在Java中,使用"jar"命令来对将JavaWeb应用打包成一个War包,jar命 ...
- MyEclipse Spring 学习总结三 SpringMVC
MyEclipse Spring 学习总结三 SpringMVC 一.SpringMVC原理 1.Springmvc 框架介绍 1)Spring 框架停工了构建Web应用程序的全功能MVC模块.Spr ...
- Quartz定时任务学习(二)web应用/Quartz定时任务学习(三)属性文件和jar
web中使用Quartz 1.首先在web.xml文件中加入 如下内容(根据自己情况设定) 在web.xml中添加QuartzInitializerServlet,Quartz为能够在web应用中使用 ...
- MyBatis学习系列三——结合Spring
目录 MyBatis学习系列一之环境搭建 MyBatis学习系列二——增删改查 MyBatis学习系列三——结合Spring MyBatis在项目中应用一般都要结合Spring,这一章主要把MyBat ...
随机推荐
- PAT甲 1095 解码PAT准考证/1153 Decode Registration Card of PAT(优化技巧)
1095 解码PAT准考证/1153 Decode Registration Card of PAT(25 分) PAT 准考证号由 4 部分组成: 第 1 位是级别,即 T 代表顶级:A 代表甲级: ...
- Spring MVC 简介
- 国内物联网平台(6):庆科云FogCloud
国内物联网平台(6)——庆科云FogCloud 马智 平台定位 FogCloud 快速接入智能硬件 FogCloud为开发者提供便捷的智能硬件接入服务,真正实现敏捷开发,快速迭代. FogCloud提 ...
- JS控制A标记的href跳转
var a = document.getElementById("aHref"); a.href = '/user'; //取消<a>标签原先的onclick事件,使& ...
- Percona5.6源码安装
---恢复内容开始--- 系统环境:CentOS 6.8 1.安装依赖包 yum install gcc-c++ make cmake bison bison-devel ncurses-devel ...
- css 选择器;盒模型
一.引入方式:(1)CSS 层叠样式表 作用:修饰网页结构 (2)css的三种引入方式 - 行内样式 注意:行内样式的优先级是最高的 - 内接样式 - 外接样式 二.css选择器 基础选择器 * 通配 ...
- matplotlib类
1.plt.subplot 在matplotlib下,一个Figure对象可以包含多个子图(Axes),可以使用subplot()快速绘制,其调用形式如下:subplot(numRows, numCo ...
- jupyter notebook 设置默认目录
1.打开 cmd 输入命令 jupyter notebook --generate-config 可以看到生成文件的路径,这个就是生成的配置文件jupyter_notebook_config.py, ...
- Java内存区域与内存溢出异常---对象的创建
对象的创建 在语言层面,创建一个对象通常仅仅是一个new关键字而已.在虚拟机层面,虚拟机遇到一个new指令时,首先回去检查这个指令的参数是能在常量池中定位到一个类的符号引用,并检查这个符号引用代表 ...
- HDU6299 Balanced Sequence (多校第一场1002) (贪心)
Balanced Sequence Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others ...