1. 语法对比
入口文件引入
requirejs 的引入和入口文件的引入是同一个 script 标签
//在引入 requirejs 的 script 标签的 data-main 属性引入入口文件<script data-main="src/main.js" src="https://cdn.bootcdn.net/ajax/libs/require.js/2.3.6/require.min.js"></script>
systemjs 的引入和入口文件的引入是两个单独的 script 标签
//引入 systemjs<script src="https://cdn.bootcdn.net/ajax/libs/systemjs/6.13.0/system.min.js"></script>//script 标签指明 type,加载入口文件<script type="systemjs-module" src="/src/main.js"></script>
模块定义方式
requirejs 使用 define() 方法定义模块,原生支持具名模块定义。
define(['./b.js'], function(b) {return function() {console.log('我是 a.js')b.sayHi()}})
systemjs 使用 System.register() 方法定义模块,可通过插件 named-register.js 实现具名模块定义。
System.register(['/src/b.js'], (exports) => {let b;return {setters: [(module) => {b = module}],execute() {exports({default: () => {console.log('我是 a.js')b.sayHi()}})}}})
PS:
具名模块定义在节省文件请求数量,进行多个模块合并在一个文件里的时候很有用。如果不进行模块合并,其实可以直接使用匿名模块,匿名模块的模块名字 id 是默认以其路径为唯一 id。
模块路径映射方式
require.config({baseUrl: 'lib',paths: {'compute': 'compute/main'}});
<script type="systemjs-importmap">{"imports": {"myquery": "/deps/myquery.js"}}</script>// Alternatively:<script type="systemjs-importmap" src="path/to/map.json" crossorigin="anonymous"></script>
模块加载方式(动态导入)
require(['src/a.js', 'myquery'], function(a, myquery) {console.log('I am main')a()console.log(myquery)})
System.import()
加载其他模块定义方式的模块
requirejs 使用 shim
require.config({shim: { // 支持iife全局模式的模块'backbone': {//These script dependencies should be loaded before loading//backbone.jsdeps: ['underscore', 'jquery'],//Once loaded, use the global 'Backbone' as the//module value.exports: 'Backbone'},'underscore': {exports: '_'},},packages: {} // 支持 commonjs 模式的模块})
systemjs 使用 pluggable extras加载其他模式的模块
循环依赖
requirejs 支持循环依赖
//"a" needs "b" and "b" needs "a"//Inside b.js:define(["require", "a"],function(require, a) {//"a" in this case will be null if "a" also asked for "b",//a circular dependency.return function(title) {return require("a").doSomething();}});// requirejs 中的循环依赖用 require 改写
systemjs 支持循环依赖
PS: 循环依赖本身是一种代码设计问题,代码编写过程中应该避免循环依赖的出现,但有时候循环依赖也是必须的,无法避免的。两种工具都有对循环依赖的处理。
live bindings
2. script loading
requirejs
requirejs 使用 head.appendChild(script)的方式进行模块脚本加载。
systemjs
systemjs 使用 head.appendChild(script)的方式进行模块脚本加载,同时在加载完成后又 head.removeChild了脚本模块。
3. 浏览器支持
requirejs
systemjs
充分支持到 IE 11,若要支持 IE11 之前版本的浏览器,需要引入 polyfill ,有 promise / fetch 等等 polyfill。
4. 是否支持 file 协议本地读取文件
requirejs
systemjs
5. 性能对比

