Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

babel-plugin-ember-modules-api-polyfill

Package Overview
Dependencies
Maintainers
3
Versions
41
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

babel-plugin-ember-modules-api-polyfill - npm Package Compare versions

Comparing version 1.4.2 to 1.5.0

2

package.json
{
"name": "babel-plugin-ember-modules-api-polyfill",
"version": "1.4.2",
"version": "1.5.0",
"description": "Polyfill for Ember JS API.",

@@ -5,0 +5,0 @@ "main": "src/index.js",

# babel-plugin-ember-modules-api-polyfill
[![Greenkeeper badge](https://badges.greenkeeper.io/ember-cli/babel-plugin-ember-modules-api-polyfill.svg)](https://greenkeeper.io/)
> This plugin transforms [Javscript modules API](https://github.com/emberjs/rfcs/blob/master/text/0176-javascript-module-api.md) import statements
> back to the legacy "global" ember object syntax
## Example
```js
import { inject } from "@ember/service"
```
back to the legacy
```js
const inject = Ember.inject.service
```
## Installation
`npm install --save babel-plugin-ember-modules-api-polyfill`
## Why
This plugin provides an API polyfill to allow ember addon authors to adopt the new
[Javscript modules API](https://github.com/emberjs/rfcs/blob/master/text/0176-javascript-module-api.md) whilst still maintaining backwards
compatibility with older versions of Ember that do not support the new modules API.
The intention of this Babel plugin is to also allow for a transition period and allow applications to exist in a mixed state whilst transitioning
from the old "global" ember object pattern, into the new modular pattern.
# How
Using the [ember-rfc176-data](https://github.com/ember-cli/ember-rfc176-data) package, that contains the official mapping of old global
object names to the new JS modules API import statements, addons that adopt the new API can be transpiled back to the legacy format if Ember-CLI
detects that the host application ember version does not support the new modules API.
The plugin supports both default `import Component from "@ember/component"` and named `import { inject } from "@ember/service"` import statements,
converting their syntax back to separate `const` variables within the source file. This transpilation is done at compile time by Ember CLI.
In order for ember addon developers to adopt this new API syntax, they must declare a dependency on `ember-cli-babel:v6.6.0` or above in their
package.json:
```json
{
"dependencies": {
"ember-cli-babel": "^6.6.0"
}
}
```

@@ -45,8 +45,29 @@ 'use strict';

let removals = [];
let specifiers = path.get('specifiers');
let importPath = node.source.value;
let importPath = node.source.value;
if (!reverseMapping[importPath]) {
// not a module provided by emberjs/rfcs#176
// so we have nothing to do here
return;
if (importPath === 'ember') {
// For `import Ember from 'ember'`, we can just remove the import
// and change `Ember` usage to to global Ember object.
let specifierPath = specifiers.find(specifierPath => {
if (specifierPath.isImportDefaultSpecifier()) {
return true;
}
// TODO: Use the nice Babel way to throw
throw new Error(`Unexpected non-default import from 'ember'`);
});
let local = specifierPath.node.local;
if (local.name !== 'Ember') {
// Repalce the node with a new `var name = Ember`
replacements.push(
t.variableDeclaration('var', [
t.variableDeclarator(
local,
t.identifier('Ember')
),
])
);
}
removals.push(specifierPath);
}

@@ -57,54 +78,58 @@

// Iterate all the specifiers and attempt to locate their mapping
path.get('specifiers').forEach(specifierPath => {
let specifier = specifierPath.node;
let importName;
// Only walk specifiers if this is a module we have a mapping for
if (mapping) {
// imported is the name of the module being imported, e.g. import foo from bar
const imported = specifier.imported;
// Iterate all the specifiers and attempt to locate their mapping
specifiers.forEach(specifierPath => {
let specifier = specifierPath.node;
let importName;
// local is the name of the module in the current scope, this is usually the same
// as the imported value, unless the module is aliased
const local = specifier.local;
// imported is the name of the module being imported, e.g. import foo from bar
const imported = specifier.imported;
// We only care about these 2 specifiers
if (
specifier.type !== 'ImportDefaultSpecifier' &&
specifier.type !== 'ImportSpecifier'
) {
return;
}
// local is the name of the module in the current scope, this is usually the same
// as the imported value, unless the module is aliased
const local = specifier.local;
// Determine the import name, either default or named
if (specifier.type === 'ImportDefaultSpecifier') {
importName = 'default';
} else {
importName = imported.name;
}
// We only care about these 2 specifiers
if (
specifier.type !== 'ImportDefaultSpecifier' &&
specifier.type !== 'ImportSpecifier'
) {
return;
}
if (isBlacklisted(blacklist, importPath, importName)) {
return;
}
// Determine the import name, either default or named
if (specifier.type === 'ImportDefaultSpecifier') {
importName = 'default';
} else {
importName = imported.name;
}
// Extract the global mapping
const global = mapping[importName];
if (isBlacklisted(blacklist, importPath, importName)) {
return;
}
// Ensure the module being imported exists
if (!global) {
throw path.buildCodeFrameError(`${importPath} does not have a ${importName} import`);
}
// Extract the global mapping
const global = mapping[importName];
removals.push(specifierPath);
// Ensure the module being imported exists
if (!global) {
throw path.buildCodeFrameError(`${importPath} does not have a ${importName} import`);
}
// Repalce the node with a new `var name = Ember.something`
replacements.push(
t.variableDeclaration('var', [
t.variableDeclarator(
local,
t.memberExpression(t.identifier('Ember'), t.identifier(global))
),
])
);
});
removals.push(specifierPath);
// Repalce the node with a new `var name = Ember.something`
replacements.push(
t.variableDeclaration('var', [
t.variableDeclarator(
local,
t.memberExpression(t.identifier('Ember'), t.identifier(global))
),
])
);
});
}
if (removals.length === node.specifiers.length) {

@@ -111,0 +136,0 @@ path.replaceWithMultiple(replacements);

@@ -132,1 +132,17 @@ 'use strict';

});
describe(`import from 'ember'`, () => {
matches(
`import Ember from 'ember';`,
``
);
matches(
`import Em from 'ember';`,
`var Em = Ember;`
);
matches(
`import Asdf from 'ember';`,
`var Asdf = Ember;`
);
});
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc