浅谈Webpack(一)
什么是webpack?
Webpack 是一个前端资源加载/打包工具(Module Bundler),它能把各种资源,例如JS(含JSX)、coffee、样式(含less/sass)、图片等都作为模块来使用和处理。
只需要相对简单的配置就可以提供前端工程化需要的各种功能,并且如果有需要它还可以被整合到其他比如 Grunt / Gulp 的工作流。
我们可以直接使用 require(XXX) 的形式来引入各模块,即使它们可能需要经过编译(比如JSX和sass),但我们无须在上面花费太多心思,因为 webpack 有着各种健全的加载器(loader)在默默处理这些事情。
为什么使用webpack?
现在的网站已经演化成 web app:
- 一个页面内依赖着越来越多的 JavaScript
- 现代浏览器有着越来越多的
- 虽然单页内代码越来越多,但全页刷新越来越少
这意味着,客户端有着越来越多的代码。
一个大的代码库需要良好的组织,这需要模块系统来把代码库拆分成模块。
加载器loader
loader是把一个资源文件作为入参转换为另一个资源文件的 node.js 函数。
例如,可以通过loader来让 webpack 来加载 CoffeeScript 或 JSX 文件。
如果loader发布在 npm 上,那么可以通过下面的两个命令来安装
$ npm install xxx-loader --save $ npm install xxx-loader --save-dev
安装webpack
$ npm install -g webpack
配置webpack
每个项目下都必须配置有一个 webpack.config.js ,它就是一个配置项,告诉webpack它需要做什么
看示例:
1 const webpack = require('webpack'); 2 3 module.exports = { 4 devtool: 'inline-source-map', 5 6 //页面入口文件配置 7 entry: [ 8 './public/entry.jsx', 9 'webpack-hot-middleware/client' 10 ], 11 12 //入口文件输出配置 13 output: { 14 path: __dirname, 15 publicPath: '/assets/', 16 filename: 'bundle.js' 17 }, 18 module: { 19 //加载器配置 20 loaders: [{ 21 test: /\.(js|jsx)$/, 22 exclude: /node_modules/, 23 loader: 'babel', 24 query: { 25 presets: ['es2015', 'react'] 26 } 27 }, 28 { 29 test:/\.css$/, 30 exclude:/node_modules/, 31 loader:'style!css' 32 }, 33 { 34 test: /\.(woff|woff2)$/, 35 loader: 'url-loader?limit=10000&mimetype=application/font-woff' 36 }, 37 { 38 test: /\.ttf$/, 39 loader: 'url?limit=10000&mimetype=application/octet-stream' 40 }, 41 { 42 test: /\.eot$/, 43 loader: 'file' 44 }, 45 { 46 test: /\.svg$/, 47 loader: 'url?limit=10000&mimetype=image/svg+xml' 48 }, 49 { 50 test: require.resolve('jquery'), 51 loader: 'expose?$!expose?jQuery' 52 }, 53 { 54 test: /\.(png|jpg)$/, 55 loader: 'url-loader?limit=8192' 56 } 57 ] 58 }, 59 60 //插件项 61 plugins: [ 62 // Webpack 1.0 63 new webpack.optimize.OccurenceOrderPlugin(), 64 // Webpack 2.0 fixed this mispelling 65 // new webpack.optimize.OccurrenceOrderPlugin(), 66 new webpack.HotModuleReplacementPlugin(), 67 new webpack.NoErrorsPlugin() 68 ] 69 };
1、plugins是插件项,这里我们用了三个插件方法:
webpack.optimize.OccurenceOrderPlugin(),webpack.HotModuleReplacementPlugin(),webpack.NoErrorsPlugin();
(1).webpack 给每个模块和分块分配了 id 来识别它们。webpack 可以通过new webpack.optimize.OccurenceOrderPlugin()给最常用的 id 分配最简短的 id 来进行优化;
(2).webpack.NoErrorsPlugin()是选择性的,主要的功能是当更改完的程序码有语法错误时不要重新整理。当错误修改后,画面会自动重新整理。
(3).webpack.HotModuleReplacementPlugin():Webpack-dev-server结合后端服务器的热替换配置
2、entry 是页面入口文件配置,output 是对应输出项配置(即入口文件最终要生成什么名字的文件、存放到哪里),其语法大致为:
1 { 2 entry:{ 3 page1: "./page1", 4 //支持数组形式,将加载数组中的所有模块,但以最后一个模块作为输出 5 page2: ["./entry1", "./entry2"] 6 }, 7 output:{ 8 path: "dist/js/page", 9 filename: "[name].bundle.js" 10 } 11 }
该段代码最终会生成一个 page1.bundle.js 和 page2.bundle.js,并存放到 ./dist/js/page 文件夹下。
3、module.loaders 是最关键的一块配置。它告知 webpack 每一种文件都需要使用什么加载器来处理:
module: { //加载器配置 loaders: [ //.css 文件使用 style-loader 和 css-loader 来处理 { test: /\.css$/, loader: 'style-loader!css-loader' }, //.js 文件使用 jsx-loader 来编译处理 { test: /\.js$/, loader: 'jsx-loader?harmony' }, //.scss 文件使用 style-loader、css-loader 和 sass-loader 来编译处理 { test: /\.scss$/, loader: 'style!css!sass?sourceMap'}, //图片文件使用 url-loader 来处理,小于8kb的直接转为base64 { test: /\.(png|jpg)$/, loader: 'url-loader?limit=8192'} ] }
如上,"-loader"其实是可以省略不写的,多个loader之间用“!”连接起来。
注意所有的加载器都需要通过 npm 来加载,并建议查阅它们对应的 readme 来看看如何使用。
关于 webpack.config.js 更详尽的配置可以参考这里。
运行webpack
$ webpack --display-error-details
后面的参数“--display-error-details”是推荐加上的,方便出错时能查阅更详尽的信息(比如 webpack 寻找模块的过程),从而更好定位到问题。