WebPack:更优秀的模块依赖管理工具,及require.js的缺陷

jopen 9年前
注* 之前的这篇文章: 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