WebPack:更優秀的模塊依賴管理工具,及require.js的缺陷

jopen 9年前發布 | 65K 次閱讀 前端技術 webpack
注* 之前的這篇文章: JavaScript代碼組織結構良好的5個特點,作者以reuqire.js為舉例,提出應該使用模塊化的代碼組織方式去管理你的JavaScript代碼,并提出了一些注意事項,在此文的評論中有人指出WebPack是比require.js更為優秀的代碼組織管理工具,并列舉了require.js的一些缺陷。

WebPack  是一個模塊打包工具,你可以使用WebPack管理你的模塊依賴,并編繹輸出模塊們所需的靜態文件。

它有兩種模塊加載模式

同步加載模式: CommonJS (Node.JS)的模式

var commonjs = require("./commonjs");

異步加載模式:即 AMD 模式,與require.js相同

define(["amd-module", "../file"], function(amdModule, file) {
    require(["big-module/big/file"], function(big) {
        var stuff = require("../my/stuff");
    });
});

注* 與異步加載相比(AMD),同步加載的寫法要簡單得多,不必處理諸多回調。但在前端采用此方案的性能會非常非常差,無法投入生產環境,所以各種模塊加載工具都會自帶一些build工具,按照代碼內定義的模塊依賴關系,將所需模塊按依賴次序壓縮合并,打包成一兩個靜態文件,以下來自該評論:

如果你用過webpack,你就不會用require.js去組織你的代碼。

webpack的優勢:

- require.js的所有功能它都有
- 編繹過程更快,因為require.js會去處理不需要的文件

還有一個額外的好處就是你不需要再做一個封裝的函數,require.js中你得這樣:

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

然后你就會發現你有十級深度的依賴,這太扯了,你不得不使用下面的結構。

define(function(require, exports, module){
    var _ = require('underscore');
    var helpers = require('./helpers');
    var constants = require('../constants');
    var utils = require('../utils');

現在你需要一個很大的封裝去定義每個模塊,然后你需要在在require.js的配制文件中將每個模塊的路徑都配出來(下面是我以前用的一個配制):

require.config({
    baseUrl: '/scripts',
    paths: {
        '非死book'          : '//connect.非死book.net/en_US/all',
        // '非死book'       : '//connect.非死book.net/en_US/sdk/debug'
        'requirejs'         : '../bower_components/requirejs/require',
        'react'             : '../bower_components/react/react-with-addons',
        'underscore'        : '../bower_components/lodash/dist/lodash',
        'futures-requirejs' : '../bower_components/futures-requirejs/future',
        'jquery'            : '../bower_components/jquery/jquery',
        // 'phaser'         : '../bower_components/phaser/build/phaser',
        'phaser.filters'    : '../bower_components/phaser/filters/',
        'phaser'            : '../thirdParty/phaser/Phaser',
        'snap'              : '../bower_components/Snap.svg/dist/snap.svg',
        'proton'            : '../thirdParty/Proton',
        'copyProperties'    : '../thirdParty/copyProperties',
        'flux'              : '../bower_components/flux/dist/Flux',
        'eventEmitter'      : '../bower_components/eventEmitter/EventEmitter',
        'pixi'              : '../bower_components/pixi/bin/pixi',
        'crossroads'        : '../bower_components/crossroads/dist/crossroads',
        'signals'           : '../bower_components/js-signals/dist/signals',
        'hasher'            : '../bower_components/hasher/dist/js/hasher',
        'async'             : '../bower_components/async/lib/async',
        'socket.io-client'  : '../bower_components/socket.io-client/dist/socket.io',
        'html2canvas'       : '../bower_components/html2canvas/build/html2canvas.min',
        'hammer'            : '../bower_components/hammerjs/hammer',
        'touch-emulator'    : '../bower_components/hammer-touchemulator/touch-emulator',
        'moment'            : '../bower_components/moment/moment',
        // 'famous'         : '../bower_components/famous',
        'tinygradient'      : '../bower_components/tinygradient/tinygradient',
        'page'              : '../bower_components/page/index',
        // 'faker'          : '../bower_components/faker/dist/faker',
        'faker'             : '../thirdParty/Faker',
        'perlin'            : '../thirdParty/Perlin',
        'tinycolor'         : '../vendors/tinycolor',
        // 'flux'           : '../../node_modules/flux/index',
        'client'            : './',
        'errors'            : './errors',
        'server'            : '../../server',
    },
    packages: [{
        name     : 'API2',
        location : '../bower_components/api2/src/',
        main     : 'API'
    }],
    shim: {
        'phaser.filters/Fire': {
            deps: ['phaser'],
        },
        'page': {
            exports: 'page'
        },
        'snap' : {
            exports: 'Snap'
        },
        'html2canvas' : {
            exports: 'html2canvas'
        },
        '非死book' : {
            exports: 'FB'
        },
        // 'underscore': {
        //     deps: [],
        //     exports: '_'
        // },
        'phaser': {
            exports: 'Phaser'
        },
        'pixi': {
            exports: 'PIXI'
        },
        'hammer': {
            exports: 'Hammer'
        },
        'touch-emulator': {
            exports: 'TouchEmulator'
        },
        'proton': {
            exports: 'Proton'
        },
        'moment': {
            exports: 'moment'
        }
    }
});

但是你用webpack你不需要做上面這些東西,你只需要:

var react = require('react');

真的,不需要任何模塊的定義。

當然,如果你需要一些特別的別名,你需要寫多一點,這是一個webpack.config的例子:

alias: {
    // Build
    //  - Webpack config;
    webpackConfig : absPath('webpack.config.js'),
    // Structure
    //  - Aliases to the big building blocks of the app;
    server        : absPath('/src/server/'),
    assets        : absPath('/src/assets/'),
    app           : absPath('/src/app/'),
    client        : absPath('/src/client/'),
    // Components
    //  - Aliases to npm, bower and other modules;
    bowerComponents : absPath('bower_components'),
    otherModules    : absPath('other_modules'),
    nodeModules     : absPath('node_modules'),
    // Application
    //  - Aliases for the most used files in the app;
    errors          : 'client/errors',
    constants       : 'client/constants',
    utils           : 'client/utils',
    RCSSW           : 'client/utils/RCSSW',
    'react-tooltip' : 'otherModules/react-tooltip/src/index.js',

    // Custom libs
    //  - Rename some libs;
    //  - Non npm libs;
    API2           : 'bowerComponents/api2/src/API',
    copyProperties : 'otherModules/copyProperties',
    eventEmitter   : 'wolfy87-eventemitter',
    hammer         : 'hammerjs',
    underscore     : 'lodash',

    // We use the exact same PIXI that Phaser uses.
    PIXI          : "otherModules/phaser/PIXIWrapper.js",
    pixi          : "otherModules/phaser/PIXIWrapper.js",
    // phaser     : "nodeModules/phaser/dist/phaser-arcade-physics.js",
    phaserUnFixed : "nodeModules/phaser/build/custom/phaser-no-physics.js",
    phaser        : "otherModules/phaser/phaser-wrapper.js",
    tinycolor     : 'tinycolor2', // Yes, is 2, is right!
    // As said here http://非死book.github.io/react/docs/addons.html    react     : 'react/addons',
}

注意到區別了嗎?非常明顯。

你在瀏覽器定義的層次需要在package.json文件中配置。

來自:http://ourjs.com/detail/54963e2a8a34fa3204000013
 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!