webpack学习笔记
注意本笔记只能作为参考,如有错误希望大家指正一下。
基础属性例子
const HtmlWebpackPlugin = require('html-webpack-plugin'); // 通过 npm 安装
const webpack = require('webpack'); // 用于访问内置插件
const config = {
entry: './path/to/my/entry/file.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'my-first-webpack.bundle.js'
}
module: {
rules: [
{ test: /\.txt$/, use: 'raw-loader' }
]
},
plugins: [
new HtmlWebpackPlugin({template: './src/index.html'})
]
};
module.exports = config;
入口(entry)
描述:指定哪个文件应当被当做构建的入口。
webpack会构建一个依赖图,就像一个图(数据结构中)一样。如果没有被任何一个文件依赖过的文件[模块],是不会被打包到最后的结果文件中的。
let rendererConfig = {
...
entry: {
renderer: path.join(__dirname, '../src/renderer/main.js')
},
...
}
- 这一段表明webpack将从根目录的../src/renderer/main.js.
- 其中path是node当中内置的模块 详情
注意可配置多个入口。其中renderer为[name],可以在出口处的产生文件的名字中使用。
出口(output)
output 属性告诉 webpack 在哪里输出它所创建的 bundles(结果文件),以及如何命名这些文件,默认值为 ./dist。
let rendererConfig = {
...
output: {
filename: '[name].js',
libraryTarget: 'commonjs2',
path: path.join(__dirname, '../dist/electron')
},
...
}
filename:
要生成的文件的名字,其中[name]是一开始entry的名字,如果有多个entry会生成多个文件
libraryTarget:
此配置的作用是控制 webpack 打包的内容是如何暴露的。请注意这个选项需要和output.library所绑定的值一起产生作用。CommonJS,将库的返回值分配给exports对象的由output.library指定的属性。正如名字所指,这个选项可以使用在 CommonJS 环境。
path:
生成文件的路径
值得注意的是通常output.library和output.libraryTarget会一起使用,这两个属性是为了将程序打成可用的npm包而存在的,library制定了暴露的属性名而libraryTarget则指定了该属性挂在哪个对象上。
常用的output.libraryTarget
libraryTarget名 | 挂载的对象 |
---|---|
var | 库的返回值会被分配到使用用var申明的变量上,这也是默认的值 |
this | 挂载在this对象 |
windows | 挂载在windows对象 |
CommonJS | 库的返回值挂载在exports对象 |
CommonJS 环境,一种公有的JavaScript规范。例如node是遵循这个规范的。CommonJS
开发工具(devtool)
这一选项是用于表明生成Source Maps的方式
Source Maps:为了解决打包生成后的文件丢失了原本的格式和行信息而导致的调试时,无法打断点的问题。(具体打包后的文件都是一大行,而我目前维护的一个项目还是用的gulp,没有办法进行断点调试。)
在webpack的配置文件中配置source maps,需要配置devtool,它有以下四种不同的配置选项,各具优缺点,如下:
devtool选项 | 配置结果 |
---|---|
source-map | 在一个单独的文件中产生一个完整且功能完全的文件。这个文件具有最好的source map,但是它会减慢打包速度; |
cheap-module-source-map | 在一个单独的文件中生成一个不带列映射的map,不带列映射提高了打包速度,但是也使得浏览器开发者工具只能对应到具体的行,不能对应到具体的列(符号),会对调试造成不便; |
eval-source-map | 使用eval打包源文件模块,在同一个文件中生成干净的完整的source map。这个选项可以在不影响构建速度的前提下生成完整的sourcemap,但是对打包后输出的JS文件的执行具有性能和安全的隐患。在开发阶段这是一个非常好的选项,在生产阶段则一定不要启用这个选项; |
cheap-module-eval-source-map | 这是在打包文件时最快的生成source map的方法,生成的Source Map 会和打包后的JavaScript文件同行显示,没有列映射,和eval-source-map选项具有相似的缺点; |
上述选项由上到下打包速度越来越快,不过同时也具有越来越多的负面作用,较快的打包速度的后果就是对打包后的文件的的执行有一定影响。
let rendererConfig = {
...
devtool: '#cheap-module-eval-source-map',
...
}
loader
loader 用于对模块的源代码进行转换。loader 可以使你在 import 或"加载"模块时预处理文件。
loader的主要作用在于能够帮助在加载模块(文件)是进行对文件的预处理,这使你可以将ts文件直接通过相应的load模块转换成js后打包进入目标文件。
基本结构:
module.exports = {
...
module: {
rules: [
{ test: /\.css$/, use: 'css-loader' },
{ test: /\.ts$/, use: 'ts-loader' }
]
}
...
};
注意rules属性一定包含在module属性之中,user当中可以可以配置多个loader
test:决定那些文件会使用之后的模块
use :决定使用哪些模块进行加载转换
除此之外在load当中还可以配置很多种属性。
module.exports = {
...
module: {
rules: [
...
{
test: /\.js$/,
use: 'babel-loader',
exclude: /node_modules/
},
...
]
}
...
};
在上面这个例子当中。
exclude属性,不包括/node_modules/文件夹下的内容。
module.exports = {
...
module: {
rules: [
...
{
test: /\.scss$/,
use: ['vue-style-loader', 'css-loader', 'sass-loader']
},
...
]
}
...
};
在这一个例子当中。
use属性当中配置了多个loader,这会使webpack从右往左依次链式加载源文件。
从右往左的主要原因只是因为,Webpack选择了compose方式。只是一个习惯。
module.exports = {
...
module: {
rules: [
...
{
test: /\.vue$/,
use: {
loader: 'vue-loader',
options: {
extractCSS: process.env.NODE_ENV === 'production',
loaders: {
sass: 'vue-style-loader!css-loader!sass-loader?indentedSyntax=1',
scss: 'vue-style-loader!css-loader!sass-loader',
less: 'vue-style-loader!css-loader!less-loader'
}
}
}
},
...
]
}
...
};
在上面这个例子当中
出现了options,extractCSS,和叹号,问号这几个新的关键词。
-
options:针对某个具体的loader的配置,注意query和options都是当前loader需要的特殊配置(可选)。
webpack2.5之前为query,之后为options。其效果是一致的。
在本次案例当中,针对.vue结尾的文件为VueJS的文件,其中既有html又有js,而针对css,可能会有解析sass,scss,less的style标签。所以需要依赖别的模块来加载。 -
extractCSS:(暂时还没确定,可能是表明提取CSS)
-
叹号,问号:叹号标示分割,就和之前use属性当中写数组是一样的。而问号则是表示loader所需的参数,关联问号前的loader。
常用loader:
插件(plugins)
插件目的在于解决 loader 无法实现的其他事。webpack 插件是一个具有 apply 属性的 JavaScript 对象。
module.exports = {
...
plugins: [
new VueLoaderPlugin(),
new MiniCssExtractPlugin({filename: 'styles.css'}),
new HtmlWebpackPlugin({
filename: 'index.html',
template: path.resolve(__dirname, '../src/index.ejs'),
minify: {
collapseWhitespace: true,
removeAttributeQuotes: true,
removeComments: true
},
nodeModules: process.env.NODE_ENV !== 'production'
? path.resolve(__dirname, '../node_modules')
: false
}),
new webpack.HotModuleReplacementPlugin(),
new webpack.NoEmitOnErrorsPlugin()
],
...
};
由于插件可以携带参数/选项,你必须在 webpack 配置中,向 plugins 属性传入 new 实例,以及在new的时候向其传入对象参数。
关于插件的顺序,webpack的插件确实存在加载顺序,但是,通常,在绑定编译器和编译插件时,不必考虑排序,因为插件作者会公开特定事件,而作者会绑定特定的事件。
常用插件以及配置
请查看此篇
网友评论