@xiaoqq
2017-01-23T10:53:45.000000Z
字数 4835
阅读 1167
Webpack
webpack是MODULE BUNDLER,他的目的就是把有依赖关系的各种文件打包成一系列的静态资源。
WebPack可以看做是模块打包机:它做的事情是,分析你的项目结构,找到JavaScript模块以及其它的一些浏览器不能直接运行的拓展语言(Scss,TypeScript等),并将其打包为合适的格式以供浏览器使用。
webpack简单点来说就就是一个配置文件,所有的魔力都是在这一个文件中发生的。 这个配置文件主要分为三大块:
服务器端的 Node.js 遵循 CommonJS规范,该规范的核心思想是允许模块通过 require 方法来同步加载所要依赖的其他模块,然后通过 exports 或 module.exports 来导出需要暴露的接口。
require("module");
require("../file.js");
exports.doStuff = function() {};
module.exports = someValue;
规范其实只有一个主要接口 define(id?, dependencies?, factory)
,它要在声明模块的时候指定所有的依赖 dependencies,并且还要当做形参传到 factory 中,对于依赖的模块提前执行,依赖前置。
define("module", ["dep1", "dep2"], function(d1, d2) {
return someExportedValue;
});
require(["module", "../file"], function(module, file) { /* ... */ });
Common Module Definition 规范和 AMD 很相似,尽量保持简单,并与 CommonJS 和 Node.js 的 Modules 规范保持了很大的兼容性。
define(function(require, exports, module) {
var $ = require('jquery');
var Spinning = require('./spinning');
exports.doSomething = ...
module.exports = ...
})
EcmaScript6 标准增加了 JavaScript 语言层面的模块体系定义。ES6 模块的设计思想,是尽量的静态化,使得编译时就能确定模块的依赖关系,以及输入和输出的变量。
import "jquery";
export function doStuff() {}
module "localModule" {}
可以兼容多种模块风格,尽量可以利用已有的代码,不仅仅只是 JavaScript 模块化,还有 CSS、图片、字体等资源也需要模块化。
分块传输,按需进行懒加载,在实际用到某些模块的时候再增量更新,才是较为合理的模块加载方案。
require("./style.css");
require("./style.less");
require("./template.jade");
require("./image.png");
代码拆分
Webpack 有两种组织模块依赖的方式,同步和异步。异步依赖作为分割点,形成一个新的块。在优化了依赖树后,每一个异步区块都作为一个文件被打包。
Loader
Webpack 本身只能处理原生的 JavaScript 模块,但是 loader 转换器可以将各种类型的资源转换成 JavaScript 模块。这样,任何资源都可以成为 Webpack 可以处理的模块。
智能解析
Webpack 有一个智能解析器,几乎可以处理任何第三方库,无论它们的模块形式是 CommonJS、 AMD 还是普通的 JS 文件。甚至在加载依赖的时候,允许使用动态表达式 require("./templates/" + name + ".jade")。
插件系统
Webpack 还有一个功能丰富的插件系统。大多数内容功能都是基于这个插件系统运行的,还可以开发和使用开源的 Webpack 插件,来满足各式各样的需求。
快速运行
Webpack 使用异步 I/O 和多级缓存提高运行效率,这使得 Webpack 能够以令人难以置信的速度快速增量编译。
npm install webpack-dev-server --save-dev
编写config文件:
module.exports = {
entry: __dirname+ '/app/index.js',
output: {
path: __dirname+'/build',
filename: 'bundle.js'
}
};
运行webpack
命令,并且在html文件中引用bundle.js
文件
Webpack 本身只能处理 JavaScript 模块,如果要处理其他类型的文件,就需要使用 loader 进行转换。Loader 可以理解为是模块和资源的转换器,它本身是一个函数,接受源文件作为参数,返回转换的结果。这样,我们就可以通过 require 来加载任何类型的模块或文件,比如 CoffeeScript、 JSX、 LESS 或图片。
Loader的特性:
按照惯例,而非必须,loader 一般以 xxx-loader 的方式命名,xxx 代表了这个 loader 要做的转换功能,比如 json-loader。
例如:
css:npm install css-loader style-loader
url:npm install url-loader --save-dev
es6:npm install babel-loader babel-preset-es2015 --save-dev
安装完成之后,在配置文件中添加module.loaders属性:
module.exports = {
...
module: {
loaders: [
{test: /\.css$/, loader: ['style', 'css']}
]
}
...
}
webpack还可以安装一些第三方插件
例如:可以自动生成html的插件:npm install html-webpack-plugin
var HtmlwebpackPlugin = require('html-webpack-plugin');
plugins: [
new HtmlwebpackPlugin({
title: 'Hello World app'
})
]
使用webpack-dev-server 开发服务是一个更好的选择,它将在 localhost:8080 启动一个 express 静态资源 web 服务器,并且会以监听模式自动运行 webpack。
npm install webpack-dev-server -g
当然,也可以在配置文件中配置:
devServer: {
historyApiFallback: true,
hot: true,
inline: true,
progress: true,
},
然后在package.json中编写脚本
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "webpack-dev-server --inline"
},
运行命令 npm start
一个比较完整的配置文件:
var HtmlwebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: __dirname + '/app/index.js',
output: {
path: __dirname + '/build',
filename: 'bundle.js'
},
module: {
loaders: [
{ test: /\.css$/, loader: ['style', 'css'] }
]
},
devServer: {
historyApiFallback: true,
hot: false,
inline: true,
progress: true,
},
devtool: 'source-map',
plugins: [
new HtmlwebpackPlugin({
title: 'Hello World app'
})
]
};
var path = require('path');
var webpack = require('webpack');
var productVersion = "2016120101";
module.exports = {
devtool: 'source-map',
entry: [
'webpack-hot-middleware/client',
'./src/index'
],
output: {
path: __dirname + '/scripts/',
filename: 'bundle.js',
publicPath: '/scripts/',
chunkFilename: '[name].chunk.js?v=' + productVersion,
},
plugins: [
new webpack.HotModuleReplacementPlugin()
],
resolve: {
extensions: ['.js']
},
module: {
loaders: [{
test: /\.js$/,
loaders: ['babel-loader'],
exclude: /node_modules/,
include: path.resolve(__dirname, 'src')
}, {
test: /\.less?$/,
loaders: [
'style-loader',
'css-loader',
'less-loader?{"sourceMap":true}'
],
exclude: /node_modules/,
include: path.resolve(__dirname, 'src')
}, {
test: /\.(jpe?g|png|gif|svg)$/,
loader: 'url-loader',
query: {
limit: 10240
}
}]
}
};
参考文章[1]