Skip to content
This repository was archived by the owner on Jun 4, 2024. It is now read-only.

Add babel helpers and support for named chunks. #30

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
"babel-cli": "^6.22.2",
"babel-core": "^6.22.1",
"babel-eslint": "^7.1.1",
"babel-plugin-external-helpers": "^6.22.0",
"babel-preset-airbnb": "^2.1.1",
"babel-register": "^6.22.0",
"chai": "^4.0.0",
Expand Down
44 changes: 38 additions & 6 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,54 @@ import syntax from 'babel-plugin-syntax-dynamic-import';

const TYPE_IMPORT = 'Import';

const buildImport = template(`
const buildImport = opts => template(`
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i think it might be nice if we explicitly destructured the template substitutions (and explicitly referenced them on line 12) instead of having it be implicit?

(new Promise((resolve) => {
require.ensure([], (require) => {
resolve(require(SOURCE));
});
requireLogic
}${opts.webpackChunkName ? ', webpackChunkName' : ''});
}))
`);
`)(opts);

export default () => ({
const chunkNamePattern = /webpackChunkName: "(.+)"/;

export default ({ types }) => ({
inherits: syntax,

visitor: {
CallExpression(path) {
if (path.node.callee.type === TYPE_IMPORT) {
const importPath = path.node.arguments[0];

let webpackChunkName;
importPath.leadingComments = (importPath.leadingComments || []).filter((comment) => {
const matches = chunkNamePattern.exec(comment.value);
// Create a StringLiteral node for use in the babel-template.
webpackChunkName = matches ? types.StringLiteral(matches[1]) : undefined;
return !matches;
});

/**
* Create the resolve(require('path')) call.
* This utilizes babel-helpers to properly handle default and named exports.
*/
const requireLogic = types.callExpression( // eslint-disable-line
types.identifier('resolve'), [
types.callExpression(
/**
* Wrap the require call with the require wildcard babel helper
* This helps to reduce boilerplate while sticking as closely
* as possible to the spec of import()
*/
this.addHelper('interopRequireWildcard'), [
types.callExpression(types.identifier('require'), [importPath]),
],
),
],
);

const newImport = buildImport({
SOURCE: path.node.arguments,
requireLogic,
webpackChunkName,
});
path.replaceWith(newImport);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
const testModule = new Promise(resolve => {
require.ensure([], require => {
resolve(require('test-module'));
resolve(babelHelpers.interopRequireWildcard(require('test-module')));
});
});
7 changes: 7 additions & 0 deletions test/fixtures/basic-import/expected-internal-helpers.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }

const testModule = new Promise(resolve => {
require.ensure([], require => {
resolve(_interopRequireWildcard(require('test-module')));
});
});
Original file line number Diff line number Diff line change
@@ -1,23 +1,23 @@
new Promise(resolve => {
require.ensure([], require => {
resolve(require('test-module'));
resolve(babelHelpers.interopRequireWildcard(require('test-module')));
});
}).then(() => new Promise(resolve => {
require.ensure([], require => {
resolve(require('test-module-2'));
resolve(babelHelpers.interopRequireWildcard(require('test-module-2')));
});
}));

Promise.all([new Promise(resolve => {
require.ensure([], require => {
resolve(require('test-1'));
resolve(babelHelpers.interopRequireWildcard(require('test-1')));
});
}), new Promise(resolve => {
require.ensure([], require => {
resolve(require('test-2'));
resolve(babelHelpers.interopRequireWildcard(require('test-2')));
});
}), new Promise(resolve => {
require.ensure([], require => {
resolve(require('test-3'));
resolve(babelHelpers.interopRequireWildcard(require('test-3')));
});
})]).then(() => {});
25 changes: 25 additions & 0 deletions test/fixtures/chained-import/expected-internal-helpers.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }

new Promise(resolve => {
require.ensure([], require => {
resolve(_interopRequireWildcard(require('test-module')));
});
}).then(() => new Promise(resolve => {
require.ensure([], require => {
resolve(_interopRequireWildcard(require('test-module-2')));
});
}));

Promise.all([new Promise(resolve => {
require.ensure([], require => {
resolve(_interopRequireWildcard(require('test-1')));
});
}), new Promise(resolve => {
require.ensure([], require => {
resolve(_interopRequireWildcard(require('test-2')));
});
}), new Promise(resolve => {
require.ensure([], require => {
resolve(_interopRequireWildcard(require('test-3')));
});
})]).then(() => {});
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@ const MODULE = 'test-module';

new Promise(resolve => {
require.ensure([], require => {
resolve(require(MODULE));
resolve(babelHelpers.interopRequireWildcard(require(MODULE)));
});
});
new Promise(resolve => {
require.ensure([], require => {
resolve(require(`test-${MODULE}`));
resolve(babelHelpers.interopRequireWildcard(require(`test-${MODULE}`)));
});
});
14 changes: 14 additions & 0 deletions test/fixtures/dynamic-argument/expected-internal-helpers.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }

const MODULE = 'test-module';

new Promise(resolve => {
require.ensure([], require => {
resolve(_interopRequireWildcard(require(MODULE)));
});
});
new Promise(resolve => {
require.ensure([], require => {
resolve(_interopRequireWildcard(require(`test-${MODULE}`)));
});
});
1 change: 1 addition & 0 deletions test/fixtures/named-imports/actual.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
const a = import(/* webpackChunkName: "some-path" */ './somePath');
5 changes: 5 additions & 0 deletions test/fixtures/named-imports/expected-external-helpers.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
const a = new Promise(resolve => {
require.ensure([], require => {
resolve(babelHelpers.interopRequireWildcard(require('./somePath')));
}, 'some-path');
});
7 changes: 7 additions & 0 deletions test/fixtures/named-imports/expected-internal-helpers.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }

const a = new Promise(resolve => {
require.ensure([], require => {
resolve(_interopRequireWildcard(require('./somePath')));
}, 'some-path');
});
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
function getModule(path) {
return new Promise(resolve => {
require.ensure([], require => {
resolve(require('test-module'));
resolve(babelHelpers.interopRequireWildcard(require('test-module')));
});
});
}
Expand Down
11 changes: 11 additions & 0 deletions test/fixtures/nested-import/expected-internal-helpers.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }

function getModule(path) {
return new Promise(resolve => {
require.ensure([], require => {
resolve(_interopRequireWildcard(require('test-module')));
});
});
}

getModule().then(() => {});
11 changes: 7 additions & 4 deletions test/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { expect } from 'chai';
import { join } from 'path';
import { readdirSync, statSync, readFileSync } from 'fs';

import testPlugin from './testPlugin';
import { testPluginWithHelpers, testPluginWithoutHelpers } from './testPlugin';

const FIXTURE_PATH = join(__dirname, 'fixtures');

Expand All @@ -13,10 +13,13 @@ const testFolders = readdirSync(FIXTURE_PATH).filter(file => (
describe('babel-plugin-dynamic-import-webpack', () => {
testFolders.forEach((folderName) => {
const actual = readFileSync(join(FIXTURE_PATH, folderName, 'actual.js'), 'utf8');
const expected = readFileSync(join(FIXTURE_PATH, folderName, 'expected.js'), 'utf8');
const expectedInternalHelpers = readFileSync(join(FIXTURE_PATH, folderName, 'expected-internal-helpers.js'), 'utf8');
const expectedExternalHelpers = readFileSync(join(FIXTURE_PATH, folderName, 'expected-external-helpers.js'), 'utf8');
it(`works with ${folderName}`, () => {
const result = testPlugin(actual);
expect(result.trim()).to.equal(expected.trim());
const resultInternalHelpers = testPluginWithHelpers(actual);
const resultExternalHelpers = testPluginWithoutHelpers(actual);
expect(resultInternalHelpers.trim()).to.equal(expectedInternalHelpers.trim());
expect(resultExternalHelpers.trim()).to.equal(expectedExternalHelpers.trim());
});
});
});
13 changes: 12 additions & 1 deletion test/testPlugin.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,17 @@
import { transform } from 'babel-core';

export default function testPlugin(code) {
export function testPluginWithoutHelpers(code) {
const result = transform(code, {
plugins: [
'./src/index.js',
'external-helpers',
],
});

return result.code;
}

export function testPluginWithHelpers(code) {
const result = transform(code, {
plugins: ['./src/index.js'],
});
Expand Down