webpack4学习笔记(二)
webpack打包各种javascript文件
(本文只是提供一个学习记录,大部分内容来自网络)
一,打包js文件和es6代码
1,webpack命令打包js文件
Tip: 在webpack4.x之前可以直接在命令行工具中使用webpack命令(全局安装了webpack),webpack4.x之后需要安装webpack-cli
1 webpack --entry .\src\app.js --output ./src/b.js --mode development
webpack --entry <入口文件> --output <输出文件> --mode 模式
更多具体参数可以:webpack --help
Config options: --config Path to the config file [string] [default: webpack.config.js or webpackfile.js] --config-register, -r Preload one or more modules before loading the webpack configuration [array] [default: module id or path] --config-name Name of the config to use [string] --env Environment passed to the config, when it is a function --mode Enable production optimizations or development hints. [choices: "development", "production", "none"] Basic options: --context The base directory (absolute path!) for resolving the `entry` option. If `output.pathinfo` is set, the included pathinfo is shortened to this directory. [string] [default: The current directory] --entry The entry point(s) of the compilation. [string] --watch, -w Enter watch mode, which rebuilds on file change. [boolean] --debug Switch loaders to debug mode [boolean] --devtool A developer tool to enhance debugging. [string] -d shortcut for --debug --devtool eval-cheap-module-source-map --output-pathinfo [boolean] -p shortcut for --optimize-minimize --define process.env.NODE_ENV="production" [boolean] --progress Print compilation progress in percentage [boolean] Module options: --module-bind Bind an extension to a loader [string] --module-bind-post Bind an extension to a post loader [string] --module-bind-pre Bind an extension to a pre loader [string] Output options: --output, -o The output path and file for compilation assets --output-path The output directory as **absolute path** (required). [string] [default: The current directory] --output-filename Specifies the name of each output file on disk. You must **not** specify an absolute path here! The `output.path` option determines the location on disk the files are written to, filename is used solely for naming the individual files. [string] [default: [name].js] --output-chunk-filename The filename of non-entry chunks as relative path inside the `output.path` directory. [string] [default: filename with [id] instead of [name] or [id] prefixed] --output-source-map-filename The filename of the SourceMaps for the JavaScript files. They are inside the `output.path` directory. [string] --output-public-path The `publicPath` specifies the public URL address of the output files when referenced in a browser. [string] --output-jsonp-function The JSONP function used by webpack for async loading of chunks. [string] --output-pathinfo Include comments with information about the modules. [boolean] --output-library Expose the exports of the entry point as library [array] --output-library-target Type of library [string] [choices: "var", "assign", "this", "window", "self", "global", "commonjs", "commonjs2", "commonjs-module", "amd", "umd", "umd2", "jsonp"] Advanced options: --records-input-path Store compiler state to a json file. [string] --records-output-path Load compiler state from a json file. [string] --records-path Store/Load compiler state from/to a json file. This will result in persistent ids of modules and chunks. An absolute path is expected. `recordsPath` is used for `recordsInputPath` and `recordsOutputPath` if they left undefined.[string] --define Define any free var in the bundle [string] --target Environment to build for [string] --cache Cache generated modules and chunks to improve performance for multiple incremental builds. [boolean] [default: It's enabled by default when watching] --watch-stdin, --stdin Stop watching when stdin stream has ended [boolean] --watch-aggregate-timeout Delay the rebuilt after the first change. Value is a time in ms. [number] --watch-poll Enable polling mode for watching [string] --hot Enables Hot Module Replacement [boolean] --prefetch Prefetch this request (Example: --prefetch ./file.js) [string] --provide Provide these modules as free vars in all modules (Example: --provide jQuery=jquery) [string] --labeled-modules Enables labeled modules [boolean] --plugin Load this plugin [string] --bail Report the first error as a hard error instead of tolerating it. [boolean] [default: null] --profile Capture timing information for each module. [boolean] [default: null] Resolving options: --resolve-alias Redirect module requests [string] --resolve-extensions Redirect module requests [array] --resolve-loader-alias Setup a loader alias for resolving [string] Optimizing options: --optimize-max-chunks Try to keep the chunk count below a limit --optimize-min-chunk-size Minimal size for the created chunk --optimize-minimize Enable minimizing the output. Uses optimization.minimizer. [boolean] Stats options: --color, --colors Force colors on the console [boolean] [default: (supports-color)] --no-color, --no-colors Force no colors on the console [boolean] --sort-modules-by Sorts the modules list by property in module [string] --sort-chunks-by Sorts the chunks list by property in chunk [string] --sort-assets-by Sorts the assets list by property in asset [string] --hide-modules Hides info about modules [boolean] --display-exclude Exclude modules in the output [string] --display-modules Display even excluded modules in the output [boolean] --display-max-modules Sets the maximum number of visible modules in output [number] --display-chunks Display chunks in the output [boolean] --display-entrypoints Display entry points in the output [boolean] --display-origins Display origins of chunks in the output [boolean] --display-cached Display also cached modules in the output [boolean] --display-cached-assets Display also cached assets in the output [boolean] --display-reasons Display reasons about module inclusion in the output [boolean] --display-depth Display distance from entry point for each module [boolean] --display-used-exports Display information about used exports in modules (Tree Shaking) [boolean] --display-provided-exports Display information about exports provided from modules [boolean] --display-optimization-bailout Display information about why optimization bailed out for modules [boolean] --display-error-details Display details about errors [boolean] --display Select display preset [string] [choices: "", "verbose", "detailed", "normal", "minimal", "errors-only", "none"] --verbose Show more details [boolean] --info-verbosity Controls the output of lifecycle messaging e.g. Started watching files... [string] [choices: "none", "info", "verbose"] [default: "info"] --build-delimiter Display custom text after build output[string]
2,使用配置文件打包
const path = require('path');
module.exports = {
mode: "production", // "production" | "development" | "none" // Chosen mode tells webpack to use its built-in optimizations accordingly.
entry: "./app/entry", // string | object | array // 这里应用程序开始执行
//entry: ["./app/entry1", "./app/entry2"]
//entry: {
// a: "./app/entry-a",
// b: ["./app/entry-b", "./app/entry-b"]
// }
// webpack 开始打包
output: {
// webpack 如何输出结果的相关选项
path: path.resolve(__dirname, "dist"), // string
// 所有输出文件的目标路径
// 必须是绝对路径(使用 Node.js 的 path 模块)
filename: "bundle.js", // string // 「入口分块(entry chunk)」的文件名模板(出口分块?)
publicPath: "/assets/", // string // 输出解析文件的目录,url 相对于 HTML 页面
library: "MyLibrary", // string,
// 导出库(exported library)的名称
libraryTarget: "umd", // 通用模块定义 // 导出库(exported library)的类型
/* 高级输出配置(点击显示) */ },
module: {
// 关于模块配置
rules: [
// 模块规则(配置 loader、解析器等选项)
{
test: /\.jsx?$/,
include: [
path.resolve(__dirname, "app")
],
exclude: [
path.resolve(__dirname, "app/demo-files")
],
// 这里是匹配条件,每个选项都接收一个正则表达式或字符串
// test 和 include 具有相同的作用,都是必须匹配选项
// exclude 是必不匹配选项(优先于 test 和 include)
// 最佳实践:
// - 只在 test 和 文件名匹配 中使用正则表达式
// - 在 include 和 exclude 中使用绝对路径数组
// - 尽量避免 exclude,更倾向于使用 include
issuer: { test, include, exclude },
// issuer 条件(导入源)
enforce: "pre",
enforce: "post",
// 标识应用这些规则,即使规则覆盖(高级选项)
loader: "babel-loader",
// 应该应用的 loader,它相对上下文解析
// 为了更清晰,`-loader` 后缀在 webpack 2 中不再是可选的
// 查看 webpack 1 升级指南。
options: {
presets: ["es2015"]
},
// loader 的可选项
},
{
test: /\.html$/,
test: "\.html$"
use: [
// 应用多个 loader 和选项
"htmllint-loader",
{
loader: "html-loader",
options: {
/* ... */
}
}
]
},
{ oneOf: [ /* rules */ ] },
// 只使用这些嵌套规则之一
{ rules: [ /* rules */ ] },
// 使用所有这些嵌套规则(合并可用条件)
{ resource: { and: [ /* 条件 */ ] } },
// 仅当所有条件都匹配时才匹配
{ resource: { or: [ /* 条件 */ ] } },
{ resource: [ /* 条件 */ ] },
// 任意条件匹配时匹配(默认为数组)
{ resource: { not: /* 条件 */ } }
// 条件不匹配时匹配
],
/* 高级模块配置(点击展示) */ },
resolve: {
// 解析模块请求的选项
// (不适用于对 loader 解析)
modules: [
"node_modules",
path.resolve(__dirname, "app")
],
// 用于查找模块的目录
extensions: [".js", ".json", ".jsx", ".css"],
// 使用的扩展名
alias: {
// 模块别名列表
"module": "new-module",
// 起别名:"module" -> "new-module" 和 "module/path/file" -> "new-module/path/file"
"only-module$": "new-module",
// 起别名 "only-module" -> "new-module",但不匹配 "only-module/path/file" -> "new-module/path/file"
"module": path.resolve(__dirname, "app/third/module.js"),
// 起别名 "module" -> "./app/third/module.js" 和 "module/file" 会导致错误
// 模块别名相对于当前上下文导入
},
/* 可供选择的别名语法(点击展示) */
/* 高级解析选项(点击展示) */ },
performance: {
hints: "warning", // 枚举 maxAssetSize: 200000, // 整数类型(以字节为单位)
maxEntrypointSize: 400000, // 整数类型(以字节为单位)
assetFilter: function(assetFilename) {
// 提供资源文件名的断言函数
return assetFilename.endsWith('.css') || assetFilename.endsWith('.js');
}
},
devtool: "source-map", // enum // 通过在浏览器调试工具(browser devtools)中添加元信息(meta info)增强调试
// 牺牲了构建速度的 `source-map' 是最详细的。
context: __dirname, // string(绝对路径!)
// webpack 的主目录
// entry 和 module.rules.loader 选项
// 相对于此目录解析
target: "web", // 枚举 // 包(bundle)应该运行的环境
// 更改 块加载行为(chunk loading behavior) 和 可用模块(available module)
externals: ["react", /^@angular\//], // 不要遵循/打包这些模块,而是在运行时从环境中请求他们
stats: "errors-only", // 精确控制要显示的 bundle 信息
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: [
// ...
],
// 附加插件列表
/* 高级配置(点击展示) */}
说明:
1,运行配置文件,可在package.json下的`scripts`里添加: { "build": "webpack --config webpack.config.js"},其中配置文件的默认名字为webpack.config.js,如果是其他名字可以用config指认。
2,entry对象是webpack的打包的入口文件。webpack会根据entry的配置进行查找入口文件和所有依赖文件并且构建bundle
3,output对象指示webpack将如何去输出,以及在哪里输出你的[bundle,asset和其他你所打包或者使用wenbpack载入的任何内容]
3,webpack配合babel打包ES6、7
由于ES6的普及和得心用手,几乎所有项目中都会使用es6语法。但是浏览器对其支持并不友好,所以需要把es6降级到大部分浏览器都能解析的es5。babel就是这样一个作用的工具。
babel-loader: 只是起到一个通知的角色,通知babel你需要干活了,在webpack中是这样的:
module: { rules: [ { test: /\.js$/, exclude: /node_modules/, use: { loader: 'babel-loader', options: { // 这个配置项我们一般单独拿出来,创建一个‘.babelrc’文件来单独存放配置项 presets: ['@babel/preset-env'],// babel预设 plugin: ['@babel/plugin-proposal-object-rest-spread'] // 所需要使用的插件 } } } }
babel-core
如果说 babel-loader 是告诉webpack我要对js文件进行代码兼容性编译,那么,webpack接下来就是要找babel,而bable的入口就是 babel-core ,只有通过它,webpack才能使用各种babel的api(前提是你安装了相关的api)。
babel-preset-env
首先,介绍下历史背景,对了解和学习 babel-preset-env 有帮助。
最初,为了让开发者能够尽早用上新的JS特性,babel团队开发了babel-preset-latest。这个preset比较特殊,它是多个preset的集合(es2015+),并且随着ECMA规范的更新更增加它的内容。
比如,当前(2018.06.02),它包含的preset包括:es2017、es1016、es2015。
到了明年,可能它包含的preset就包括:es2018、es2017、es2016、es2015。
随着时间的推移,babel-preset-latest 包含的插件越来越多,这带来了如下问题:
- 加载的插件越来越多,编译速度会越来越慢;
- 随着用户浏览器的升级,ECMA规范的支持逐步完善,编译至低版本规范的必要性在减少(比如ES6 -> ES5),多余的转换不单降低执行效率,还浪费带宽。
因为上述问题的存在,babel官方推出了babel-preset-env插件。它可以根据开发者的配置,按需加载插件。配置项大致包括:
- 需要支持的平台:比如node、浏览器等。
- 需要支持的平台的版本:比如支持node@6.1等。
默认配置的情况下,它跟 babel-preset-latest 是等同的,会加载从es2015开始的所有preset。
配置文件.babelrc如下,当前为默认配置
{ "presets": [ "env" ] }
同时可以针对node和浏览器版本去进行不同的配置,比如,我们需要支持IE8+,chrome2+,那么可以这样配置:
{ "presets": [ ["env", { "targets": { "browsers": [ "ie >= 8", "chrome >= 62" ] } }] ] }
预设只能将ES6语法编译为你指定的ES版本语法,例如:箭头函数,但是像 Array.from 这样的API呢他无能为力。那么,怎么办呢?
babel-polypill、babel-runtime
babel-polypill就是提供了es6新方法的解决方案,不过使用的时候是在入口文件全局引入,这样会污染全局变量,所以需要babel-runtime,这样就不要全局引入而导致全局变量的污染
{ "presets": [ ["env", { "targets": { "browsers": [ "ie >= 8", "chrome >= 62" ] } }] ], "plugins": ["transform-runtime"] // }

浙公网安备 33010602011771号