Permalink
Browse files

feat(bundler): support npm package shipped in native es module

Although Nodejs doesn't support es module by default, webpack supports it. Some npm packages like bpmn-js are shipped in native es module format. They are consumable by webpack but not Nodejs. This feature closes the gap between our built-in bundler and webpack.

closes #872
  • Loading branch information...
huochunpeng committed Sep 3, 2018
1 parent 8fa8800 commit 1669a6f358ffa8183b52ea4f6ae7791247c9b62b
@@ -14,32 +14,23 @@ var parse = require('../lib/parse');
// https://github.com/requirejs/r.js/issues/980
module.exports = function cjs(fileName, fileContents, forceWrap) {
// Strip out comments.
try {
var preamble = '',
commonJsProps = parse.usesCommonJs(fileName, fileContents);
var preamble = '',
commonJsProps = parse.usesCommonJs(fileName, fileContents);
// First see if the module is not already RequireJS-formatted.
if (!forceWrap && (parse.usesAmdOrRequireJs(fileName, fileContents) || !commonJsProps)) {
return fileContents;
}
if (commonJsProps && (commonJsProps.dirname || commonJsProps.filename)) {
preamble = 'var __filename = module.uri || \'\', ' +
'__dirname = ' +
'__filename.substring(0, __filename.lastIndexOf(\'/\') + 1); ';
}
// Construct the wrapper boilerplate.
fileContents = 'define(function (require, exports, module) {' +
preamble +
fileContents +
'\n});\n';
} catch (e) {
console.log('commonJs.convert: COULD NOT CONVERT: ' + fileName +
', so skipping it. Error was: ' + e);
// First see if the module is not already RequireJS-formatted.
if (!forceWrap && (parse.usesAmdOrRequireJs(fileName, fileContents) || !commonJsProps)) {
return fileContents;
}
return fileContents;
if (commonJsProps && (commonJsProps.dirname || commonJsProps.filename)) {
preamble = 'var __filename = module.uri || \'\', ' +
'__dirname = ' +
'__filename.substring(0, __filename.lastIndexOf(\'/\') + 1); ';
}
// Construct the wrapper boilerplate.
return 'define(function (require, exports, module) {' +
preamble +
fileContents +
'\n});\n';
};
@@ -0,0 +1,10 @@
'use strict';
const transform = require('babel-core').transform;
// use babel to translate native es module into AMD module
module.exports = function es(fileName, fileContents) {
return transform(fileContents, {
babelrc: false,
plugins: ['transform-es2015-modules-amd']
}).code;
};
@@ -2,6 +2,7 @@
const path = require('path');
const findDeps = require('./find-deps').findDeps;
const cjsTransform = require('./amodro-trace/read/cjs');
const esTransform = require('./amodro-trace/read/es');
const allWriteTransforms = require('./amodro-trace/write/all');
const logger = require('aurelia-logging').getLogger('BundledSource');
@@ -117,7 +118,21 @@ exports.BundledSource = class {
// forceCjsWrap bypasses a r.js parse bug.
// See lib/amodro-trace/read/cjs.js for more info.
let forceCjsWrap = !!modulePath.match(/\/(cjs|commonjs)\//i);
let contents = cjsTransform(modulePath, this.contents, forceCjsWrap);
let contents;
try {
contents = cjsTransform(modulePath, this.contents, forceCjsWrap);
} catch (ignore) {
// file is not in amd/cjs format, try native es module
try {
contents = esTransform(modulePath, this.contents);
} catch (e) {
logger.error('Could not convert to AMD module, skipping ' + modulePath);
logger.error('Error was: ' + e);
contents = this.contents;
}
}
deps = findDeps(modulePath, contents);
let context = {pkgsMainMap: {}, config: {shim: {}}};
View
@@ -33,6 +33,7 @@
"aurelia-dependency-injection": "^1.0.0",
"aurelia-logging": "^1.2.0",
"aurelia-polyfills": "^1.0.0",
"babel-plugin-transform-es2015-modules-amd": "^6.24.1",
"babel-polyfill": "^6.0.0 || ^7.0.0 || ^8.0.0",
"babel-register": "^6.0.0 || ^7.0.0 || ^8.0.0",
"esprima": "^4.0.0",
@@ -202,6 +202,39 @@ exports.t = t;
.toBe("define('foo/bar/lo',['require','exports','module','./t'],function (require, exports, module) {var t = require('./t');exports.t = t;});");
});
it('transforms npm package js file in native es module format', () => {
let file = {
path: path.resolve(cwd, 'node_modules/foo/bar/lo.js'),
contents: `
import t from './t';
export {t};
`
};
let bs = new BundledSource(bundler, file);
bs._getProjectRoot = () => 'src';
bs.includedBy = {
includedBy: {
description: {
name: 'foo',
mainId: 'foo/index',
loaderConfig: {
name: 'foo',
path: '../node_modules/foo',
main: 'index'
}
}
}
};
bs._getLoaderPlugins = () => [];
bs._getLoaderConfig = () => ({paths: {}});
let deps = bs.transform();
expect(deps).toEqual(['foo/bar/t']);
expect(bs.requiresTransform).toBe(false);
// assume babel did right job for bs.contents
});
it('transforms npm package js file with named AMD module', () => {
let file = {
path: path.resolve(cwd, 'node_modules/foo/index.js'),

0 comments on commit 1669a6f

Please sign in to comment.