webpack 现在几乎是每个前端必会的工具,但是它的一些配置很容易弄晕初学者。经过我不断的学(复制)习(粘贴),终于弄明白了一点,在这里做个总结。
认识
其实以前我是用的 gulp,作为流式构建工具(stream building tools),它仅有几个特定的 API,使用的时候也是很简单,这个以后再写。
刚开始对于 webpack 我也是拒绝的,这么复杂,似乎跟 gulp 没什么区别。后来才发现,其实区别还是很大的。
webpack 是模块化构建系统(module building system),它的作用是把一切资源(js/html/css/jpg)都模块化处理,实现了按需加载。
webpack 也是一个高度可配置的,它有四个核心概念:入口(entry)、输出(output)、loader、插件(plugins)。
- entry: 定义整个编译过程的起点
- output: 定义整个编译过程的终点
- module: 定义模块module的处理方式
- plugin 对编译完成后的内容进行二度加工
- resolve.alias 定义模块的别名
开始
npm install webpack webpack-dev-server --save-dev
|
webpack.config.js
const path = require('path'); module. exports ={ entry:'./index.js',//入口文件 output:{ path:__dirname+'/dist',//另一种写法:path.resolve(__dirname, 'dist'),其中__dirname是nodejs的全局变量 filename:'bundle.js'//打包后的文件名 } }
|
tips: 对于多个入口的页面采用如下配置:
entry: { pageOne: './src/pageOne/a.js', pageTwo: './src/pageTwo/b.js', pageThree: './src/pageThree/c.js' } output: { filename: '[name].js',//webpack 会自动生成相应的文件dist/a.js... path: __dirname + '/dist' }
|
Loader
loader 用于对模块的源代码进行转换,可以使你在 require() 或”加载”模块时预处理文件。
常用的 loader 有 autoprefixer、postcss-loader、css-loader、style-loader、url-loader、file-loader、babel-loader。对于每个的详细用法可以参考相应的文档说明。
var autoprefixer = require('autoprefixer'); module: { rules: [{ test: /\.css$/, use: [{ loader: 'postcss-loader' },{ loader: 'style-loader' }, { loader: 'css-loader', options: { modules: true } }] }, { test: /\.js$/, loader: 'babel-loader',//高级版 js 处理 exclude: /node_modules/ //exclude不包括 }, { test: /\.(png|jpg|gif|svg)$/, loader: 'file-loader',//文件处理 options: { name: '[name].[ext]?[hash]' } },{ test: /\.(png|jpg|gif|woff|woff2|eot|ttf|svg)$/, loader: 'url-loader?limit=8192'//图片处理 }] postcss:[autoprefixer({browsers:['last 2 versions']})]//自动补全 }
|
说明:
- test 正则匹配文件格式
- loader 执行顺序从右往左
- css-loader 处理 css 的一些 url 及路径
- style-loader 是将 css 文件采用js动态写入 html 页面
Plugins
插件用于解决 Loader 无法解决的事情。
常用插件有:html-webpack-plugin(自动生成 HTML 文件)、extract-text-webpack-plugin(提取 CSS 文件)、CommonsChunkPlugin(提供公共代码)等。
var HtmlWebpackPlugin = require('html-webpack-plugin'); var ExtractTextPlugin = require("extract-text-webpack-plugin"); var CommonsChunkPlugin = require("CommonsChunkPlugin"); module.exports = { entry: './index.js', output: { path: __dirname + '/dist', filename: 'bundle.js' }, loaders: [{ test: /\.css$/, loader: ExtractTextPlugin.extract("style-loader", "css-loader", "postcss-loader"), options: { postcss: [ autoprefixer() ], }, }], plugins: [ new HtmlWebpackPlugin({ title: '标题', filename: 'admin.html', template: 'header.html', inject: 'body', //插入位置 favicon: './images/favico.ico', minify: true, hash: true, cache: false, showErrors: false, "chunks": { "head": { "entry": "assets/head_bundle.js", "css": ["main.css"] } } }), new ExtractTextPlugin("[name].[hash].css"), new CommonsChunkPlugin('common.js',['main','index']), //只提取 main 和 index 节点并生成 common.js,去掉方括号内则表示提取所有公共部分并生成 common.js ] }
|
webpack-dev-server
webpack-dev-server 是一个小型的 Node.js Express 服务器,它使用 webpack-dev-middleware 来服务于 webpack 的包。
var WebpackDevServer = require('webpack-dev-server'); var compiler = webpack(config); var server = new WebpackDevServer(compiler, { contentBase: "./public", //以public为根目录提供文件,默认情况下,webpack-dev-server会从项目的根目录提供文件,可以通过此选项设置文件的目录名 colors: true,//设置终端输出字体颜色 historyApiFallback: true,//当设置为true时,访问所有服务器上不存在的文件,都会被重定向到/,也就是index.html文件 inline: true//设为true时可以在文件发生变化时,更新页面 }); server.listen(8080, "localhost", function() { //可以不要这个回调 });
|
externals
如果有不想用 webpack 进行 bundle 的文件,可以使用 externals 关键字:
externals:{ 'Zepto':'window.Zepto', '$':'window.Zepto' }
|
全局变量
将第三方库如 jQuery 单独拿出来,需要用到 ProvidePlugin(webpack 内置插件):
module.exports = { entry: { app: '自己的代码入口', vendor: ['jquery'] //第三方库 }, output: { filename: '自己打包后生成的文件名', path: '路径' }, plugins: [ new webpack.ProvidePlugin({ $: 'jquery'//可以使jquery变成全局变量,不用再自己文件require('jquery')了 }), new webpack.optimize.CommonsChunkPlugin('vendor', 'vendor.bundle.js') //第三方库打包生成的文件 ] }
|
cross-env
用于解决不同系统设置NODE_ENV时的差异,实现兼容。需要另外安装。
package.json
{ "name": "webpack-demo", "version": "1.0.0", "scripts": { "dev": "cross-env NODE_ENV=dev webpack", "prod": "cross-env NODE_env=prod webpack" }, "devDependencies": { "webpack": "^2.2.0", "webpack-merge": "^2.6.1" } }
|
完整的配置
这个下次再说吧。
参考链接:webpack 中文文档