Webpack入门指南: 入口,输出,加载器和插件
Posted 奇舞周刊
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Webpack入门指南: 入口,输出,加载器和插件相关的知识,希望对你有一定的参考价值。
编者按:本文由Nero0在众成翻译平台上翻译。祝大家周末愉快,每天都有好心情~
(图片来自网络)
前端开发已经变成模块化的方式,代码的封装和结构也相应地提高了。工程化变成每一个项目非常关键的一部分,关于前端工程化的选择也非常的多。
这几年Webpack获得了很高的人气,因为它强大的功能和可扩展性,但是有一些开发者在编写配置文件的时候会感觉疑惑,较难去适应webpack的配置方式。
我们将从一个空配置文件开始,编写一些简单的配置,一步步的去完整的打包一个项目。这篇文章假定你们了解基本的 CommonJS 语法和模块的工作方式。
概念
不像其他的打包工具,Webpack 的魅力在于聚合你所有的项目依赖(不仅仅是代码,还包括其他资源文件)生成一个依赖关系网。
刚开始,这些事情可能看起来很奇怪:一个.js文件需要加载一个样式表,或者一个样式表文件检索一个被修改为模块的图片文件,但是对于 Webpack来说,这样可以让它了解你的程序包里都有哪些东西,并帮助你去转变转变和优化它们。
安装
首先添加用来初始化的npm包
npm install webpack webpack-dev-server --save-dev
接下来在项目根目录创建一个 webpack.config.js 文件,添加两条脚本命令到 package.json 文件中用作开发模式和生产模式的代码打包。
"scripts": {
"start": "webpack-dev-server",
"build": "webpack"
}
Webpack 命令会按照我们刚创建的配置文件执行,除非我们指出其他操作。
入口
有很多方式来指定我们的代码“入口点”,这个“入口点”将会是我们依赖关系网的根节点。
最简单的方式是传一个字符串:
var baseConfig = {
entry: './src/index.js'
};
也可以传一个对象,以防我们以后可能需要不止一个入口的情况。
var baseConfig = {
entry: {
main: './src/index.js'
}
};
我推荐使用后者,当项目逐渐壮大之后这样的扩展性更好。
输出
Webpack中的输出是一个对象,包含我们打包后的程序和资源将要去到的路径,以及它们采用的名称。
var path = require('path');
var baseConfig = {
entry: {
main: './src/index.js'
},
output: {
filename: 'main.js',
path: path.resolve('./build')
}
};
// export configuration
module.exports = baseConfig;
如果你想使用对象来定义入口,而不是用字符串写死输出文件的名称,可以这么做:
output: {
filename: '[name].js',
path: path.resolve('./build')
}
这样当新的条目添加进来时,Webpack会使用它们的key值来定义文件名。
当有了这些简单的配置以后,我们已经可以跑起来简单的服务,并在本地开发时使用 npm start或 npm run budil来打包我们的代码。webpack-dev-server 会监控你的代码,当项目的依赖关系中某一些环节发生改变的时候,网站会自动重载。
加载器
Webpack 存在的目标就是处理我们所有的文件依赖。
// index.js file
import helpers from '/helpers/main.js';
// Hey Webpack! I will need these styles:
import 'main.css';
这是啥?在javascript里面require一个css文件?是的!但是打包器只能准备好处理Javascript的依赖关系。 这是加载器介入的地方。
加载器提供了一种很简单的方式来拦截我们的依赖,并在打包之前提供预处理。
var baseConfig = {
// ...
module: {
rules: [
{
test: /* RegEx */,
use: [
{
loader: /* loader name */,
query: /* optional config object */
}
]
}
]
}
};
为了让加载器工作,我们需要一个正则表达式来定义我们需要修改的文件,以及一个字符串或数组用来申明我们需要使用的加载器。
样式
为了让Webpack可以处理样式,我们需要安装css和style加载器。
npm install --save-dev css-loader style-loader
css加载器将会把样式文件翻译成依赖文件,style加载器将会自动添加 `` 标签当打包后的代码在页面上被加载时。
var baseConfig = {
entry: {
main: './src/index.js'
},
output: {
filename: '[name].js',
path: path.resolve('./build')
},
module: {
rules: [
{
test: /\.css$/,
use: [
{ loader: 'style-loader' },
{ loader: 'css-loader' }
]
}
]
}
};
在这个例子里面,main.css将先经过css加载器的处理,然后是style加载器
预处理器
添加对LESS或其他css预处理器也非常简单,只需要安装相应的加载器,并添加到规则中。
rules: [
{
test: /\.less$/,
use: [
{ loader: 'style-loader' },
{ loader: 'css-loader' },
{ loader: 'less-loader' }
]
}
]
编译
JavaScript也可以被加载器转化,比如我们可以使用Babel加载器来编译脚本文件。
rules: [
{
test: /\.js$/,
use: [
{ loader: 'babel-loader' }
]
}
]
图片
Webpack有一个很棒的特性,它可以在样式表里检测出url()语句,让加载器对图片文件或链接本身做出一些改变。
// index.less file
@import 'less/vars';
body {
background-color: @background-color;
color: @text-color;
}
.logo {
background-image: url('./images/logo.svg');
}
通过添加这条规则,我们可以应用文件加载器来拷贝文件,或使用url-加载器,将图片替换为base64字符串,除非它超过字节限制,在这种情况下,它将用相对路径替换url语句,并将文件复制到输出位置。
{
test: /\.svg$/,
use: [
{
loader: 'url-loader',
query: { limit : 10000 }
}
]
}
加载器可以通过传递query对象来配置,比如我们可以配置加载器内联文件,当文件不超过10Kb的时候。
通过这样的方式来管理打包进程,我们只需要include一些必要的资源,而不是去移动有大量文件的资源文件夹,甚至很多文件你的项目根本用不上。
如果你使用 React或者类似的库,在组件内你可以使用svg-inline-loader来加载.svg文件。
插件
Webpack在打包大多数类型的资源的时候有一些默认的操作,当加载器的功能不够用的时候,我们可以使用一些插件来扩展Webpack的功能。
举例来说,Webpack默认会将样式文件打包插入,但是我们可以通过引入插件来改变这个行为。
提取资源
一个常见的用法是提取出生成好的样式文件,并且就像我们通常加载那样使用``标签。
var ExtractTextPlugin = require('extract-text-webpack-plugin');
var lessRules = {
use: [
{ loader: 'css-loader' },
{ loader: 'less-loader' }
]
};
var baseConfig = {
// ...
module: {
rules: [
// ...
{ test: /\.less$/, use: ExtractTextPlugin.extract(lessRules) }
]
},
plugins: [
new ExtractTextPlugin('main.css')
]
};
生成一个 index.html 文件
当构建一个单页面应用的时候,我们通常需要一个.html文件来承载页面。
HtmlWebpackPlugin可以自动创建index.html 文件,添加打包生成的script标签。同时也支持模板语法,可配置性很高。
var HTMLWebpackPlugin = require('html-webpack-plugin');
var baseConfig = {
// ...
plugins: [
new HTMLWebpackPlugin()
]
};
为生产模式构建
定义环境
很多库引入了报警机制,这在开发模式中非常有用,但是在生产模式中没有用(打包上线),还会增加线上包的体积。
Webpack 提供了内建的插件可以在打包过程中设置一个全局变量。
var ENV = process.env.NODE_ENV;
var baseConfig = {
// ...
plugins: [
new webpack.DefinePlugin({
'process.env.NODE_ENV': JSON.stringify(ENV)
})
]
};
我们现在需要在命令中指定环境:
"scripts": {
"start": "NODE_ENV=development webpack-dev-server",
"build": "NODE_ENV=production webpack"
}
process.env.NODE_ENV将会被一个字符串替换,使得压缩器可以去掉那些没用的开发分支。
在代码中引入警告会非常有用,当你的团队没有进入生产模式的打包进程。
if (process.env.NODE_ENV === 'development') {
console.warn('This warning will dissapear on production build!');
}
压缩
在生产模式中,我们需要给用户尽可能快的产品。通过修改代码,减少不必要的字符,捡回减少我们最后打包出来的文件大小,提升加载速度。
一个很有用的工具是 UglifyJS, 在Webpack中提供了一个内建的插件来处理我们的代码。
// webpack.config.js file
var ENV = process.env.NODE_ENV;
var baseConfig = {
// ...
plugins: []
};
if (ENV === 'production') {
baseConfig.plugins.push(new webpack.optimize.UglifyJsPlugin());
}
总结
Webpack 配置文件非常有用,并且可以根据你的需求改变文件的复杂度。多注意去好好管理,当你的项目变得复杂的时候,配置文件可能也会变得难以管理。
在这篇文章里面,我们从一个空的配置文件开始,逐步完成了可以本地开发和发布生产代码的功能配置。Webpack的功能还需要更多的探索,这些基本概念将会帮助你更熟悉和了解Webpack。
如果你想要更深入,我推荐Webpack official documentation,它在第二次发布中更新了很多新的内容。
奇舞周刊
——————————————————
领略前端技术 阅读奇舞周刊
长按二维码,关注奇舞周刊
▼
以上是关于Webpack入门指南: 入口,输出,加载器和插件的主要内容,如果未能解决你的问题,请参考以下文章