[关闭]
@xiaoqq 2017-01-23T10:53:45.000000Z 字数 4835 阅读 1167

Webpack学习笔记

Webpack


一、引言

定义:

webpack是MODULE BUNDLER,他的目的就是把有依赖关系的各种文件打包成一系列的静态资源。

WebPack可以看做是模块打包机:它做的事情是,分析你的项目结构,找到JavaScript模块以及其它的一些浏览器不能直接运行的拓展语言(Scss,TypeScript等),并将其打包为合适的格式以供浏览器使用。

webpack简单点来说就就是一个配置文件,所有的魔力都是在这一个文件中发生的。 这个配置文件主要分为三大块:

二、模块规范的比较

1. CommonJS

服务器端的 Node.js 遵循 CommonJS规范,该规范的核心思想是允许模块通过 require 方法来同步加载所要依赖的其他模块,然后通过 exports 或 module.exports 来导出需要暴露的接口。

  1. require("module");
  2. require("../file.js");
  3. exports.doStuff = function() {};
  4. module.exports = someValue;

2. AMD(Asynchronous Module Definition)

规范其实只有一个主要接口 define(id?, dependencies?, factory),它要在声明模块的时候指定所有的依赖 dependencies,并且还要当做形参传到 factory 中,对于依赖的模块提前执行,依赖前置。

  1. define("module", ["dep1", "dep2"], function(d1, d2) {
  2. return someExportedValue;
  3. });
  4. require(["module", "../file"], function(module, file) { /* ... */ });

3. CMD(Common Module Definition)

Common Module Definition 规范和 AMD 很相似,尽量保持简单,并与 CommonJS 和 Node.js 的 Modules 规范保持了很大的兼容性。

  1. define(function(require, exports, module) {
  2. var $ = require('jquery');
  3. var Spinning = require('./spinning');
  4. exports.doSomething = ...
  5. module.exports = ...
  6. })

4. ES6 模块

EcmaScript6 标准增加了 JavaScript 语言层面的模块体系定义。ES6 模块的设计思想,是尽量的静态化,使得编译时就能确定模块的依赖关系,以及输入和输出的变量。

  1. import "jquery";
  2. export function doStuff() {}
  3. module "localModule" {}

5. Webpack

可以兼容多种模块风格,尽量可以利用已有的代码,不仅仅只是 JavaScript 模块化,还有 CSS、图片、字体等资源也需要模块化。

分块传输,按需进行懒加载,在实际用到某些模块的时候再增量更新,才是较为合理的模块加载方案。

所有资源都是模块

  1. require("./style.css");
  2. require("./style.less");
  3. require("./template.jade");
  4. require("./image.png");

三、Webpack 的特点

  1. 代码拆分

    Webpack 有两种组织模块依赖的方式,同步和异步。异步依赖作为分割点,形成一个新的块。在优化了依赖树后,每一个异步区块都作为一个文件被打包。

  2. Loader

    Webpack 本身只能处理原生的 JavaScript 模块,但是 loader 转换器可以将各种类型的资源转换成 JavaScript 模块。这样,任何资源都可以成为 Webpack 可以处理的模块。

  3. 智能解析

    Webpack 有一个智能解析器,几乎可以处理任何第三方库,无论它们的模块形式是 CommonJS、 AMD 还是普通的 JS 文件。甚至在加载依赖的时候,允许使用动态表达式 require("./templates/" + name + ".jade")。

  4. 插件系统

    Webpack 还有一个功能丰富的插件系统。大多数内容功能都是基于这个插件系统运行的,还可以开发和使用开源的 Webpack 插件,来满足各式各样的需求。

  5. 快速运行

    Webpack 使用异步 I/O 和多级缓存提高运行效率,这使得 Webpack 能够以令人难以置信的速度快速增量编译。

四、Webpack使用

1. 最基本的步骤:

  1. 安装:npm install webpack-dev-server --save-dev
  2. 创建index.js 和 index.html
  3. 编写config文件:

    1. module.exports = {
    2. entry: __dirname+ '/app/index.js',
    3. output: {
    4. path: __dirname+'/build',
    5. filename: 'bundle.js'
    6. }
    7. };
  4. 运行webpack命令,并且在html文件中引用bundle.js文件

2. Loader

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属性:

  1. module.exports = {
  2. ...
  3. module: {
  4. loaders: [
  5. {test: /\.css$/, loader: ['style', 'css']}
  6. ]
  7. }
  8. ...
  9. }

3. 插件

webpack还可以安装一些第三方插件
例如:可以自动生成html的插件:npm install html-webpack-plugin

  1. var HtmlwebpackPlugin = require('html-webpack-plugin');
  2. plugins: [
  3. new HtmlwebpackPlugin({
  4. title: 'Hello World app'
  5. })
  6. ]

4. 开发环境

使用webpack-dev-server 开发服务是一个更好的选择,它将在 localhost:8080 启动一个 express 静态资源 web 服务器,并且会以监听模式自动运行 webpack。
npm install webpack-dev-server -g

当然,也可以在配置文件中配置:

  1. devServer: {
  2. historyApiFallback: true,
  3. hot: true,
  4. inline: true,
  5. progress: true,
  6. },

然后在package.json中编写脚本

  1. "scripts": {
  2. "test": "echo \"Error: no test specified\" && exit 1",
  3. "start": "webpack-dev-server --inline"
  4. },

运行命令 npm start

5. 配置文件示例

一个比较完整的配置文件:

  1. var HtmlwebpackPlugin = require('html-webpack-plugin');
  2. module.exports = {
  3. entry: __dirname + '/app/index.js',
  4. output: {
  5. path: __dirname + '/build',
  6. filename: 'bundle.js'
  7. },
  8. module: {
  9. loaders: [
  10. { test: /\.css$/, loader: ['style', 'css'] }
  11. ]
  12. },
  13. devServer: {
  14. historyApiFallback: true,
  15. hot: false,
  16. inline: true,
  17. progress: true,
  18. },
  19. devtool: 'source-map',
  20. plugins: [
  21. new HtmlwebpackPlugin({
  22. title: 'Hello World app'
  23. })
  24. ]
  25. };

Webpack2.x 配置文件

  1. var path = require('path');
  2. var webpack = require('webpack');
  3. var productVersion = "2016120101";
  4. module.exports = {
  5. devtool: 'source-map',
  6. entry: [
  7. 'webpack-hot-middleware/client',
  8. './src/index'
  9. ],
  10. output: {
  11. path: __dirname + '/scripts/',
  12. filename: 'bundle.js',
  13. publicPath: '/scripts/',
  14. chunkFilename: '[name].chunk.js?v=' + productVersion,
  15. },
  16. plugins: [
  17. new webpack.HotModuleReplacementPlugin()
  18. ],
  19. resolve: {
  20. extensions: ['.js']
  21. },
  22. module: {
  23. loaders: [{
  24. test: /\.js$/,
  25. loaders: ['babel-loader'],
  26. exclude: /node_modules/,
  27. include: path.resolve(__dirname, 'src')
  28. }, {
  29. test: /\.less?$/,
  30. loaders: [
  31. 'style-loader',
  32. 'css-loader',
  33. 'less-loader?{"sourceMap":true}'
  34. ],
  35. exclude: /node_modules/,
  36. include: path.resolve(__dirname, 'src')
  37. }, {
  38. test: /\.(jpe?g|png|gif|svg)$/,
  39. loader: 'url-loader',
  40. query: {
  41. limit: 10240
  42. }
  43. }]
  44. }
  45. };

参考文章[1]

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注