Skip to content

Commit d13c745

Browse files
committed
refactor: Use babel AST for polyfill
1 parent 1d459ed commit d13c745

File tree

6 files changed

+149
-84
lines changed

6 files changed

+149
-84
lines changed

index.js

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,31 @@
11
'use strict';
22

3-
const ReplaceImportsPreprocessor = require('./lib/replace-imports-preprocessor');
3+
const { resolve } = require('path');
44

55
module.exports = {
66
name: require('./package').name,
77

8-
setupPreprocessorRegistry(type, registry) {
9-
if (type !== 'parent') {
10-
return;
11-
}
8+
included() {
9+
this._super.included.apply(this, arguments);
1210

13-
registry.add('js', new ReplaceImportsPreprocessor());
11+
this.patchEmberModulesAPIPolyfill();
12+
},
13+
14+
patchEmberModulesAPIPolyfill() {
15+
const babel = this.parent.findOwnAddonByName
16+
? this.parent.findOwnAddonByName('ember-cli-babel') // parent is an addon
17+
: this.parent.findAddonByName('ember-cli-babel'); // parent is an app
18+
19+
if (babel.__CachedDecoratorPolyfillApplied) return;
20+
babel.__CachedDecoratorPolyfillApplied = true;
21+
22+
const { _getEmberModulesAPIPolyfill } = babel;
23+
24+
babel._getEmberModulesAPIPolyfill = function (...args) {
25+
const plugins = _getEmberModulesAPIPolyfill.apply(this, args);
26+
if (!plugins) return;
27+
28+
return [[resolve(__dirname, './lib/transpile-modules.js')], ...plugins];
29+
};
1430
}
1531
};

lib/replace-imports-preprocessor.js

Lines changed: 0 additions & 22 deletions
This file was deleted.

lib/transpile-modules.js

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
'use strict';
2+
3+
const path = require('path');
4+
5+
/**
6+
* Based on `babel-plugin-ember-modules-api-polyfill`.
7+
* @see https://github.com/ember-cli/babel-plugin-ember-modules-api-polyfill/blob/master/src/index.js
8+
*/
9+
module.exports = function (babel) {
10+
const t = babel.types;
11+
12+
const MODULE = '@glimmer/tracking';
13+
const IMPORT = 'cached';
14+
const REPLACED_MODULE = 'ember-cached-decorator-polyfill';
15+
16+
return {
17+
name: 'ember-cache-decorator-polyfill',
18+
visitor: {
19+
ImportDeclaration(path) {
20+
let node = path.node;
21+
let declarations = [];
22+
let removals = [];
23+
let specifiers = path.get('specifiers');
24+
let importPath = node.source.value;
25+
26+
// Only walk specifiers if this is a module we have a mapping for
27+
if (importPath === MODULE) {
28+
// Iterate all the specifiers and attempt to locate their mapping
29+
specifiers.forEach(specifierPath => {
30+
let specifier = specifierPath.node;
31+
let importName;
32+
33+
// imported is the name of the module being imported, e.g. import foo from bar
34+
const imported = specifier.imported;
35+
36+
// local is the name of the module in the current scope, this is usually the same
37+
// as the imported value, unless the module is aliased
38+
const local = specifier.local;
39+
40+
// We only care about these 2 specifiers
41+
if (
42+
specifier.type !== 'ImportDefaultSpecifier' &&
43+
specifier.type !== 'ImportSpecifier'
44+
) {
45+
if (specifier.type === 'ImportNamespaceSpecifier') {
46+
throw new Error(
47+
`Using \`import * as ${specifier.local.name} from '${importPath}'\` is not supported.`
48+
);
49+
}
50+
return;
51+
}
52+
53+
// Determine the import name, either default or named
54+
if (specifier.type === 'ImportDefaultSpecifier') {
55+
importName = 'default';
56+
} else {
57+
importName = imported.name;
58+
}
59+
60+
if (importName !== IMPORT) return;
61+
62+
removals.push(specifierPath);
63+
64+
declarations.push(
65+
t.importDeclaration(
66+
[
67+
t.importSpecifier(
68+
t.identifier(local.name),
69+
t.identifier(IMPORT)
70+
)
71+
],
72+
t.stringLiteral(REPLACED_MODULE)
73+
)
74+
);
75+
});
76+
}
77+
78+
if (removals.length > 0) {
79+
if (removals.length === node.specifiers.length) {
80+
path.replaceWithMultiple(declarations);
81+
} else {
82+
removals.forEach(specifierPath => specifierPath.remove());
83+
path.insertAfter(declarations);
84+
}
85+
}
86+
}
87+
}
88+
};
89+
};
90+
91+
// Provide the path to the package's base directory for caching with broccoli
92+
// Ref: https://github.com/babel/broccoli-babel-transpiler#caching
93+
module.exports.baseDir = () => path.resolve(__dirname, '..');

package.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,6 @@
4040
},
4141
"dependencies": {
4242
"@glimmer/tracking": "^1.0.4",
43-
"broccoli-replace": "^2.0.2",
4443
"ember-cache-primitive-polyfill": "^1.0.1",
4544
"ember-cli-babel": "^7.21.0"
4645
},

tests/unit/renamed-import-test.ts

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import { module, test } from 'qunit';
2+
import { tracked, cached as localCached } from '@glimmer/tracking';
3+
4+
module('Unit | Import | renamed import', function () {
5+
test('it works', function (assert) {
6+
class Person {
7+
@tracked firstName = 'Jen';
8+
lastName = 'Weber';
9+
10+
@localCached
11+
get fullName() {
12+
const fullName = `${this.firstName} ${this.lastName}`;
13+
assert.step(fullName);
14+
return fullName;
15+
}
16+
}
17+
18+
const person = new Person();
19+
assert.verifySteps([], 'getter is not called after class initialization');
20+
21+
assert.strictEqual(person.fullName, 'Jen Weber');
22+
assert.verifySteps(
23+
['Jen Weber'],
24+
'getter was called after property access'
25+
);
26+
27+
assert.strictEqual(person.fullName, 'Jen Weber');
28+
assert.verifySteps(
29+
[],
30+
'getter was not called again after repeated property access'
31+
);
32+
});
33+
});

yarn.lock

Lines changed: 1 addition & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -2005,17 +2005,6 @@ anymatch@~3.1.1:
20052005
normalize-path "^3.0.0"
20062006
picomatch "^2.0.4"
20072007

2008-
applause@^2.0.0:
2009-
version "2.0.4"
2010-
resolved "https://registry.yarnpkg.com/applause/-/applause-2.0.4.tgz#0b771418fdd1bb326a225ad031d41ba0b20cd0f4"
2011-
integrity sha512-wFhNjSoflbAEgelX3psyKSXV2iQFjuYW31DEhcCOD/bQ98VdfltLclK4p1mI6E58Qp4Q7+5RCbBdr+Nc9b5QhA==
2012-
dependencies:
2013-
lodash "^4.17.21"
2014-
optional-require "^1.0.2"
2015-
optionalDependencies:
2016-
cson-parser "^4.0.8"
2017-
js-yaml "^4.0.0"
2018-
20192008
aproba@^1.0.3, aproba@^1.1.1:
20202009
version "1.2.0"
20212010
resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a"
@@ -2036,11 +2025,6 @@ argparse@^1.0.7:
20362025
dependencies:
20372026
sprintf-js "~1.0.2"
20382027

2039-
argparse@^2.0.1:
2040-
version "2.0.1"
2041-
resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38"
2042-
integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==
2043-
20442028
arr-diff@^4.0.0:
20452029
version "4.0.0"
20462030
resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520"
@@ -3246,7 +3230,7 @@ broccoli-file-creator@^2.1.1:
32463230
broccoli-plugin "^1.1.0"
32473231
mkdirp "^0.5.1"
32483232

3249-
broccoli-filter@^1.2.2, broccoli-filter@^1.2.3, broccoli-filter@^1.3.0:
3233+
broccoli-filter@^1.2.2, broccoli-filter@^1.2.3:
32503234
version "1.3.0"
32513235
resolved "https://registry.yarnpkg.com/broccoli-filter/-/broccoli-filter-1.3.0.tgz#71e3a8e32a17f309e12261919c5b1006d6766de6"
32523236
integrity sha512-VXJXw7eBfG82CFxaBDjYmyN7V72D4In2zwLVQJd/h3mBfF3CMdRTsv2L20lmRTtCv1sAHcB+LgMso90e/KYiLw==
@@ -3509,15 +3493,6 @@ broccoli-plugin@^4.0.1, broccoli-plugin@^4.0.2, broccoli-plugin@^4.0.3:
35093493
rimraf "^3.0.0"
35103494
symlink-or-copy "^1.3.0"
35113495

3512-
broccoli-replace@^2.0.2:
3513-
version "2.0.2"
3514-
resolved "https://registry.yarnpkg.com/broccoli-replace/-/broccoli-replace-2.0.2.tgz#eb40046bb124a7f651486aece947ce28bbec30b1"
3515-
integrity sha512-1e8uyGUo8HqiKKB4oWz5nUX1rlLSRgShLxczuwSXJlmGljVWerDGF0oW5VshGAuKKYkAoDsI3Cc0TKEgo4SWTg==
3516-
dependencies:
3517-
applause "^2.0.0"
3518-
broccoli-filter "^1.3.0"
3519-
minimatch "^3.0.4"
3520-
35213496
broccoli-slow-trees@^3.0.1, broccoli-slow-trees@^3.1.0:
35223497
version "3.1.0"
35233498
resolved "https://registry.yarnpkg.com/broccoli-slow-trees/-/broccoli-slow-trees-3.1.0.tgz#8e48903f59e061bf1213963733b9e61dec2ee5d7"
@@ -4181,11 +4156,6 @@ code-point-at@^1.0.0:
41814156
resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77"
41824157
integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=
41834158

4184-
4185-
version "1.12.7"
4186-
resolved "https://registry.yarnpkg.com/coffeescript/-/coffeescript-1.12.7.tgz#e57ee4c4867cf7f606bfc4a0f2d550c0981ddd27"
4187-
integrity sha512-pLXHFxQMPklVoEekowk8b3erNynC+DVJzChxS/LCBBgR6/8AJkHivkm//zbowcfc7BTCAjryuhx6gPqPRfsFoA==
4188-
41894159
collection-visit@^1.0.0:
41904160
version "1.0.0"
41914161
resolved "https://registry.yarnpkg.com/collection-visit/-/collection-visit-1.0.0.tgz#4bc0373c164bc3291b4d368c829cf1a80a59dca0"
@@ -4564,13 +4534,6 @@ crypto-random-string@^2.0.0:
45644534
resolved "https://registry.yarnpkg.com/crypto-random-string/-/crypto-random-string-2.0.0.tgz#ef2a7a966ec11083388369baa02ebead229b30d5"
45654535
integrity sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==
45664536

4567-
cson-parser@^4.0.8:
4568-
version "4.0.9"
4569-
resolved "https://registry.yarnpkg.com/cson-parser/-/cson-parser-4.0.9.tgz#eef0cf77edd057f97861ef800300c8239224eedb"
4570-
integrity sha512-I79SAcCYquWnEfXYj8hBqOOWKj6eH6zX1hhX3yqmS4K3bYp7jME3UFpHPzu3rUew0oyfc0s8T6IlWGXRAheHag==
4571-
dependencies:
4572-
coffeescript "1.12.7"
4573-
45744537
[email protected], cssom@^0.3.4:
45754538
version "0.3.8"
45764539
resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.3.8.tgz#9f1276f5b2b463f2114d3f2c75250af8c1a36f4a"
@@ -7963,13 +7926,6 @@ js-yaml@^3.13.1, js-yaml@^3.2.5, js-yaml@^3.2.7:
79637926
argparse "^1.0.7"
79647927
esprima "^4.0.0"
79657928

7966-
js-yaml@^4.0.0:
7967-
version "4.1.0"
7968-
resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602"
7969-
integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==
7970-
dependencies:
7971-
argparse "^2.0.1"
7972-
79737929
jsbn@~0.1.0:
79747930
version "0.1.1"
79757931
resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513"
@@ -8496,11 +8452,6 @@ [email protected], lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.12, lodash@^4.17.
84968452
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.20.tgz#b44a9b6297bcb698f1c51a3545a2b3b368d59c52"
84978453
integrity sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==
84988454

8499-
lodash@^4.17.21:
8500-
version "4.17.21"
8501-
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
8502-
integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
8503-
85048455
log-symbols@^2.2.0:
85058456
version "2.2.0"
85068457
resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-2.2.0.tgz#5740e1c5d6f0dfda4ad9323b5332107ef6b4c40a"
@@ -9343,11 +9294,6 @@ onetime@^5.1.0:
93439294
dependencies:
93449295
mimic-fn "^2.1.0"
93459296

9346-
optional-require@^1.0.2:
9347-
version "1.0.3"
9348-
resolved "https://registry.yarnpkg.com/optional-require/-/optional-require-1.0.3.tgz#275b8e9df1dc6a17ad155369c2422a440f89cb07"
9349-
integrity sha512-RV2Zp2MY2aeYK5G+B/Sps8lW5NHAzE5QClbFP15j+PWmP+T9PxlJXBOOLoSAdgwFvS4t0aMR4vpedMkbHfh0nA==
9350-
93519297
optionator@^0.8.1:
93529298
version "0.8.3"
93539299
resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.3.tgz#84fa1d036fe9d3c7e21d99884b601167ec8fb495"

0 commit comments

Comments
 (0)