webpack 的基本使用方法

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 中文文档