Webpack 学习笔记。
是什么?
官方给到的解释:
webpack is a static module bundler for modern JavaScript applications.
它是一款针对JS应用的静态模块打包工具,当使用webpack处理应用程序时,它会在内部建一个依赖关系图,这个图能映射应用需要的每一个module并生成一个或多个bundles。
2018.3.12,Webpack4.0 正式发布,Sean T. Larkin 在当天发表了文章webpack 4: released today!!, 列出了新版的变动。通过查看releases可以得到changelog, 目前的最新版本是4.8.3。
使用webpack来打包module时,需要设定配置文件,默认的配置文件是webpack.config.js
,不过对于4.0及以上的版本,webpack已经不再强制要求配置文件了。针对需要设定的属性,有其相对应的默认值。
在使用webpack前,有必要了解一些重要的概念。
几个重要的概念
Entry
entry用于告诉webpack从哪个文件开始创建内部的依赖关系图,默认情况下是
./src/index.js
。 我们也可以在配置文件webpack.config.js
中自定义,比如:module.exports = { entry: './path/file.js' };
entry可以有多个,比如:
const config = { entry: { pageOne: './src/pageOne/index.js', pageTwo: './src/pageTwo/index.js', pageThree: './src/pageThree/index.js' } }; module.exports = config;
这里设置了三个entries,告诉webpack要生成三个独立的内部依赖图。
Output
output用于告诉webpack,打包编译后的文件放在哪里。主要通过给filename和path赋值的方式来指定。
看个例子:
const config = { output: { filename: 'bundle.js', path: '/home/project/public/assets' } }; module.exports = config;
这里告诉webpack,最后的输出文件是bundle.js, 存放在
'/home/project/public/assets'
下。上面提到了entry可以有多个,但是output只能有一个,不能配置多个。那么如何让每一个entry都有一个output文件而不是混合在一起呢?官方给到了一个这样的例子做参考:
{ entry: { app: './src/app.js', search: './src/search.js', }, output: { filename: '[name].js', path: __dirname + '/dist } }
这样会在
/dist
下面输出两个打包后的文件,./dist/app.js
,./dist/search.js
.Loaders
loaders用于告诉webpack,不同的文件需要用什么加载器进行处理,比如把其他非JS文件,如TS,转换成JS,或者import一些CSS文件。loader好比在导入或者加载文件时,对文件进行了一次预处理,使之符合打包要求。
设定loaders有三种方式:
在配置文件中设定
比如需要加载css,转换ts文件,可以这么用:
先在本地安装对应的loaders:
npm install --save-dev css-loader npm install --save-dev ts-loader
然后在配置文件中指定用哪个loader处理哪些文件:
module.exports = { module: { rules: [ { test: /\.css$/, use: 'css-loader' }, { test: /\.ts$/, use: 'ts-loader' } ] } };
这里告诉webpack,用css-loader处理
.css
文件,用ts-loader处理.ts
文件。在
import
中声明比如:
import Styles from 'style-loader!css-loader?modules!./styles.css';
这里用style-loader和css-loader来处理modules和
./styles.css
。使用命令行
看官方给出的例子:
webpack --module-bind jade-loader --module-bind 'css=style-loader!css-loader'
这里告诉webpack,用jade-loader处理
.jade
文件, 用style-loader和css-loader处理.css
文件。官方还给到了loader 列表以及如何write your own loader。
Plugins
loader可以用来转换某些类型的module,而plugin则用来扩展webpack的功能,比如优化bundle,管理assets。
Tapable可以提供简单的plugin接口,官方还给出了如何自己写一个plugin的教程write a plugin.
在使用某个plugin之前,需要用
require()
来将它先添加到plugins 数组中。调用时,则需要使用new
来创建一个plugin的实例。看个官方给到的例子:
const HtmlWebpackPlugin = require('html-webpack-plugin'); const webpack = require('webpack'); const config = { module: { rules: [ {test: /\.txt$\/, use: 'raw-loader'} ] }, plugins: [ new HtmlWebpackPlugin({template: './src/index.html'}); ] }; module.exports = config;
这里使用html-webpack-plugin这个plugin,将会自动生成一个index.html文件。
戳这里查看目前的plugin list。
Mode
mode用于告诉webpack, 根据mode指定的环境来启用webpack的内置优化,其实是启用了对应每个环境下的默认plugins,mode默认值是production,即生产环境。
mode的取值可以为production,development,或者none。取值为none就是不用任何默认的plugin来优化。
可以通过命令行或者config文件来设置mode:
配置文件
module.exports = { mode: 'development' };
命令行
webpack --mode=development
安装
分本地安装和全局安装:
global installation
npm install --global webpack
全局安装会让你固定在特定版本的webpack,对于使用不同版本webpack的项目而言,不是件好事。
local installation
npm install --save-dev webpack
这会在本地安装最新版的webpack,如果需要安装指定版本,可以执行:
npm install --save-dev webpack@<version> ## version是版本号
常用命令
启动:
webpack
让webpack 时时编译:
webpack --build
自定义配置文件:
webpack --config yourconfig.js
补充
如果你也是和我一样的JS新手,在了解Webpack前,有必要对模块及模块化打包进行更为清晰的了解。推荐阅读Preethi Kasireddy的这两篇JavaScript Modules: A Beginner’s Guide,JavaScript Modules Part 2: Module Bundling, 对于理解JS中的module 以及为何要bundle module有很大帮助,文中还对比了下webpack与Browserify, RequireJS等其他module bundle的差异,很有启发性。
参考
JavaScript Modules: A Beginner’s Guide