@xiaoqq
2017-01-23T10:53:45.000000Z
字数 4835
阅读 1250
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]