美文网首页
webpack 学习

webpack 学习

作者: 西柚子啊喂 | 来源:发表于2016-10-13 15:02 被阅读67次

    AMD(异步模块定义)是为浏览器环境设计的,因为 CommonJS 模块系统是同步加载的,当前浏览器环境还没有准备好同步加载模块的条件。

    AMD 定义了一套 JavaScript 模块依赖异步加载标准,来解决同步加载的问题。

    模块通过 `define` 函数定义在闭包中,格式如下:

    ```js

    define(id?: String, dependencies?: String[], factory: Function|Object);

    ```

    `id` 是模块的名字,它是可选的参数。

    `dependencies` 指定了所要依赖的模块列表,它是一个数组,也是可选的参数,每个依赖的模块的输出将作为参数一次传入 `factory` 中。如果没有指定 `dependencies`,那么它的默认值是 `["require", "exports", "module"]`。

    ```js

    define(function(require, exports, module) {})

    ```

    `factory` 是最后一个参数,它包裹了模块的具体实现,它是一个函数或者对象。如果是函数,那么它的返回值就是模块的输出接口或值。

    一些用例:

    定义一个名为 `myModule` 的模块,它依赖 `jQuery` 模块:

    ```js

    define('myModule', ['jquery'], function($) {

    // $ 是 jquery 模块的输出

    $('body').text('hello world');

    });

    // 使用

    define(['myModule'], function(myModule) {});

    ```

    注意:在 webpack 中,模块名只有局部作用域,在 Require.js 中模块名是全局作用域,可以在全局引用。

    定义一个没有 `id` 值的匿名模块,通常作为应用的启动函数:

    ```js

    define(['jquery'], function($) {

    $('body').text('hello world');

    });

    ```

    依赖多个模块的定义:

    ```js

    define(['jquery', './math.js'], function($, math) {

    // $ 和 math 一次传入 factory

    $('body').text('hello world');

    });

    ```

    模块输出:

    ```js

    define(['jquery'], function($) {

    var HelloWorldize = function(selector){

    $(selector).text('hello world');

    };

    // HelloWorldize 是该模块输出的对外接口

    return HelloWorldize;

    });

    ```

    在模块定义内部引用依赖:

    ```js

    define(function(require) {

    var $ = require('jquery');

    $('body').text('hello world');

    });

    ----------------------------------------------------------------------------------------------------

    # CommonJS 规范

    CommonJS 是以在浏览器环境之外构建 JavaScript 生态系统为目标而产生的项目,比如在服务器和桌面环境中。

    这个项目最开始是由 Mozilla 的工程师 Kevin Dangoor 在2009年1月创建的,当时的名字是 ServerJS。

    > 我在这里描述的并不是一个技术问题,而是一件重大的事情,让大家走到一起来做决定,迈出第一步,来建立一个更大更酷的东西。 —— Kevin Dangoor's [What Server Side JavaScript needs](http://www.blueskyonmars.com/2009/01/29/what-server-side-javascript-needs/)

    2009年8月,这个项目改名为 CommonJS,以显示其 API 的更广泛实用性。CommonJS 是一套规范,它的创建和核准是开放的。这个规范已经有很多版本和具体实现。CommonJS 并不是属于 ECMAScript TC39 小组的工作,但 TC39 中的一些成员参与 CommonJS 的制定。2013年5月,Node.js 的包管理器 NPM 的作者 Isaac Z. Schlueter 说 [CommonJS 已经过时,Node.js 的内核开发者已经废弃了该规范](https://github.com/nodejs/node-v0.x-archive/issues/5132#issuecomment-15432598)。

    CommonJS 规范是为了解决 JavaScript 的作用域问题而定义的模块形式,可以使每个模块它自身的命名空间中执行。该规范的主要内容是,模块必须通过 `module.exports` 导出对外的变量或接口,通过 `require()` 来导入其他模块的输出到当前模块作用域中。

    一个直观的例子:

    ```js

    // moduleA.js

    module.exports = function( value ){

    return value * 2;

    }

    ```

    ```js

    // moduleB.js

    var multiplyBy2 = require('./moduleA');

    var result = multiplyBy2(4);

    ```

    CommonJS 是同步加载模块,但其实也有浏览器端的实现,其原理是现将所有模块都定义好并通过 `id` 索引,这样就可以方便的在浏览器环境中解析了,可以参考 [require1k](https://github.com/Stuk/require1k) 和 [tiny-browser-require](https://github.com/ruanyf/tiny-browser-require) 的源码来理解其解析(resolve)的过程。

    更多关于 CommonJS 规范的内容请查看 [http://wiki.commonjs.org/wiki/CommonJS](http://wiki.commonjs.org/wiki/CommonJS)。

    ----------------------------------------------------------------------------------------------

    # 配置文件

    Webpack 在执行的时候,除了在命令行传入参数,还可以通过指定的配置文件来执行。默认情况下,会搜索当前目录的 `webpack.config.js` 文件,这个文件是一个 node.js 模块,返回一个 json 格式的配置信息对象,或者通过 `--config` 选项来指定配置文件。

    继续我们的案例,在根目录创建 `package.json` 来添加 webpack 需要的依赖:

    ```js

    {

    "name": "webpack-example",

    "version": "1.0.0",

    "description": "A simple webpack example.",

    "main": "bundle.js",

    "scripts": {

    "test": "echo \"Error: no test specified\" && exit 1"

    },

    "keywords": [

    "webpack"

    ],

    "author": "zhaoda",

    "license": "MIT",

    "devDependencies": {

    "css-loader": "^0.21.0",

    "style-loader": "^0.13.0",

    "webpack": "^1.12.2"

    }

    }

    ```

    ```bash

    # 如果没有写入权限,请尝试如下代码更改权限

    chflags -R nouchg .

    sudo chmod  775 package.json

    ```

    别忘了运行 `npm install`。

    然后创建一个配置文件 `webpack.config.js`:

    ```js

    var webpack = require('webpack')

    module.exports = {

    entry: './entry.js',

    output: {

    path: __dirname,

    filename: 'bundle.js'

    },

    module: {

    loaders: [

    {test: /\.css$/, loader: 'style!css'}

    ]

    }

    }

    ```

    同时简化 `entry.js` 中的 `style.css` 加载方式:

    ```js

    require('./style.css')

    ```

    最后运行 `webpack`,可以看到 webpack 通过配置文件执行的结果和上一章节通过命令行 `webpack entry.js bundle.js --module-bind 'css=style!css'` 执行的结果是一样的。

    -----------------------------------------------------------------------------

    # 开发环境

    当项目逐渐变大,webpack 的编译时间会变长,可以通过参数让编译的输出内容带有进度和颜色。

    ```bash

    $ webpack --progress --colors

    ```

    如果不想每次修改模块后都重新编译,那么可以启动监听模式。开启监听模式后,没有变化的模块会在编译后缓存到内存中,而不会每次都被重新编译,所以监听模式的整体速度是很快的。

    ```bash

    $ webpack --progress --colors --watch

    ```

    当然,使用 `webpack-dev-server` 开发服务是一个更好的选择。它将在 localhost:8080 启动一个 express 静态资源 web 服务器,并且会以监听模式自动运行 webpack,在浏览器打开 http://localhost:8080/ 或 http://localhost:8080/webpack-dev-server/ 可以浏览项目中的页面和编译后的资源输出,并且通过一个 socket.io 服务实时监听它们的变化并自动刷新页面。

    ```bash

    # 安装

    $ npm install webpack-dev-server -g

    # 运行

    $ webpack-dev-server --progress --colors

    ```

    相关文章

      网友评论

          本文标题:webpack 学习

          本文链接:https://www.haomeiwen.com/subject/ewmyyttx.html