什么是Webpack
webpack 是一个现代 JavaScript 应用程序的静态模块打包器(module bundler)。当 webpack 处理应用程序时,它会递归地构建一个依赖关系图(dependency graph),其中包含应用程序需要的每个模块,然后将所有这些模块打包成一个或多个 bundle。
它是高度可配置的,但是,在开始前你需要先理解四个核心概念:
- 入口(entry)
- 输出(output)
- 加载器(loader)
- 插件(plugins)
唯一入口文件 entry
1、单个入口(简写)语法
用法:entry: string|Array<string>
webpack.config.js
const config = {
entry: './path/to/my/entry/file.js'
};
module.exports = config;
entry 单个入口语法,是下面的简写:
const config = {
entry: {
main: './path/to/my/entry/file.js'
}
};
2、对象语法
用法:entry: {[entryChunkName: string]: string|Array<string>}
webpack.config.js
const config = {
entry: {
app: './src/app.js', //应用程序
vendors: './src/vendors.js' // 第三方库入口
}
};
对象语法会比较繁琐。然而,这是应用程序中定义入口的最可扩展的方式。
输出output
在 webpack 中配置 output 属性的最低要求是,将它的值设置为一个对象,包括以下两点:
filename
用于输出文件的文件名。- 目标输出目录
path
的绝对路径。
webpack.config.js
const config = {
output: {
filename: 'bundle.js',
path: '/home/proj/public/assets'
}
};
module.exports = config;
// 此配置将一个单独的 bundle.js 文件输出到 /home/proj/public/assets 目录中。
//如果配置创建了多个单独的 "chunk",则应该使用占位符来确保每个文件具有唯一的名称。
{
entry: {
app: './src/app.js',
search: './src/search.js'
},
output: {
filename: '[name].js',
path: __dirname + '/dist'
}
}
// 写入到硬盘:./dist/app.js, ./dist/search.js
加载器loader
loader 用于对模块的源代码进行转换。loader
可以使你在 import
或”加载”模块时预处理文件。loader 通过(loader)预处理函数,为 JavaScript 生态系统提供了更多能力。 用户现在可以更加灵活地引入细粒度逻辑,例如压缩、打包、语言翻译和其他更多
test
:正则表达式,用于匹配文件名(必须)loader
:需要加载的loaders
列表,使用!
分开加载多个(必须)include/exclude
:手动添加必须处理的文件(文件夹)或屏蔽不需要处理的文件(文件夹)(可选);query
:为loaders
提供额外的设置选项(可选)
使用 Loader
在你的应用程序中,有三种使用 loader 的方式:
- 配置(推荐):在
webpack.config.js
文件中指定 loader。
module: { // 加载器
rules: [{
test: /(\.jsx|\.js)$/,
use: {
loader: "babel-loader"
},
exclude: /node_modules/
}
]
},
- 内联:在每个
import
语句中显式指定 loader。
import Styles from 'style-loader!css-loader?modules!./styles.css';
- CLI:在
shell
命令中指定它们。
webpack --module-bind jade-loader --module-bind 'css=style-loader!css-loader'
CSS,CSS预处理加载
webpack提供两个工具处理样式表
css-loader
style-loader
- 二者处理的任务不同,
css-loader
使你能够使用类似@import
和url(...)
的方法实现require()
的功能,style-loader
将所有的计算后的样式加入页面中,二者组合在一起使你能够把样式表嵌入webpack打包后的JS文件中。
//安装
npm install --save-dev style-loader css-loader
插件Plugins
由于插件可以携带参数/选项,你必须在 webpack 配置中,向 plugins 属性传入 new 实例。有内置插件和扩展插件
// 方式一
const HtmlWebpackPlugin = require('html-webpack-plugin'); //通过 npm 安装
const webpack = require('webpack'); //访问内置的插件
// 方式二(内置),三(扩展)
plugin: [ // 插件
//内置压缩插件
new webpack.optimize.UglifyJsPlugin({ compressor: { warnings: false, }, }),
// 扩展插件
ComponentPlugin()
]
resolve 配置文件其他解决方案
- resolve 是配置的其他解决方案,比如
resolve.alias
可以定义模块的别名,resolve.root
可以定义绝对路径。 resolve.extensions
可以省去加载文件的后缀名,即后缀名自动补全。但是必须要在前面加一个空的字符串,否则会导致无法加载的情况。
resolve: {
extensions: ['.js', '.vue', '.json'],
alias: {
'vue$': 'vue/dist/vue.esm.js',
'@': resolve('src')
}
},
webpack-dev-server
webpack-dev-server
是一个专门为 webpack
服务的 nodejs
服务器,通过 npm install --save-dev webpack-dev-server
命令来安装。
devserver的配置选项 功能描述
contentBase 默认webpack-dev-server会为根文件夹提供本地服务器,如果想为另外一个目录下的文件提供本地服务器,应该在这里设置其所在目录(本例设置到“public”目录)
port 设置默认监听端口,如果省略,默认为”8080“
inline 设置为true,当源文件改变时会自动刷新页面
historyApiFallback 在开发单页应用时非常有用,它依赖于HTML5 history API,如果设置为true,所有的跳转将指向index.html
// webpack.config.js
devServer: {
contentBase: "./", //本地服务器所加载的页面所在的目录
colors: true, //终端中输出结果为彩色
historyApiFallback: true, //不跳转
inline: true //实时刷新
}
Babel
Babel
是一个编译 JavaScript 的平台,它的功能非常强大,可用编译 JSX,ES6,ES7,生成浏览器识别的 JavaScript 语言。需要安装多个依赖:npm install --save-dev babel-core babel-loader babel-preset-es2015 babel-preset-react
。
//webpack.config.js
module: {
loaders: [
{
test: /\.js$/,
exclude: /node_modules/,
loader: 'babel',
query: {
presets: ['es2015','react']
}
}
]
},
html-webpack-plugin
这个插件主要是针对于 html 的,可以自动生成 html 文件,尤其当使用了 hash 之后,不用困扰因 hash 的变化带来的问题。
var webpack = require('webpack')
var htmlwebpackplugin = require('html-webpack-plugin')
module.exports = {
entry: './main.js',
output: {
path: __dirname,
filename: 'bundle.js'
},
plugins: [new htmlwebpackplugin()]
}
有时候会因为 html 中必须要有一些特别的东西,不能直接生成,此时就需要配置模版:
module.exports = {
plugins:[
new htmlwebpackplugin({
filename: 'hello.html', // 生成的文件
template: 'src/template.html' // 模版文件
})
]
}
title
: 页面 titlefilename
: 输出的 HTML 文件名,默认是 index.htmltemplate
: 模板文件路径,支持加载器,比如 html!./index.htmlinject: true | 'head' | 'body' | false
,注入所有的资源到特定的 template 或者 templateContent 中,如果设置为 true 或者 body,所有的 javascript 资源将被放置到 body 元素的底部,’head’ 将放置到 head 元素中。favicon
: 添加特定的 favicon 路径到输出的 HTML 文件中。minify: {} | false
, 传递 html-minifier 选项给 minify 输出hash: true | false
, 如果为 true, 将添加一个唯一的 webpack 编译 hash 到所有包含的脚本和 CSS 文件,对于解除 cache 很有用。cache: true | false
,如果为 true, 这是默认值,仅仅在文件修改之后才会发布文件。showErrors: true | false
, 如果为 true, 这是默认值,错误信息会写入到 HTML 页面中chunks
: 允许只添加某些块 (比如,仅仅 unit test 块)chunksSortMode
: 允许控制块在添加到页面之前的排序方式,支持的值:'none' | 'default' | {function}-default:'auto'
excludeChunks
: 允许跳过某些块,(比如,跳过单元测试的块)