Skip to content

Commit

Permalink
Provide modulesMap option related to #19
Browse files Browse the repository at this point in the history
  • Loading branch information
r-murphy committed Feb 8, 2019
1 parent edabee8 commit 661e562
Show file tree
Hide file tree
Showing 6 changed files with 64 additions and 7 deletions.
14 changes: 9 additions & 5 deletions README.md
Expand Up @@ -90,7 +90,8 @@ import * as Name from "module";
```

The plugin uses a temporary name (as needed) for the initial imported variable, and then extracts the properties from it as needed.
This allows importing ES Modules which have a 'default' value, and also non-ES modules which don't. The plugin also allows for merged imports statements from the same source path into a single require and then deconstructs it accordingly.
This allows importing ES Modules which have a 'default' value, and also non-ES modules which don't.
The plugin also allows for merged imports statements from the same source path into a single require and then deconstructs it accordingly.

This:

Expand All @@ -102,7 +103,7 @@ import * as File from "app/File";
Becomes:

```js
sap.ui.define(['app/file'], function(__File) {
sap.ui.define(['app/File'], function(__File) {
function _interopRequireDefault(obj) {
return (obj && obj.__esModule && (typeof obj.default !== "undefined")) ? obj.default : obj;
}
Expand All @@ -120,9 +121,11 @@ Also refer to the `noImportInteropPrefixes` option below.
ECMAScript allows for dynamic imports calls like `import(path)` that return a Promise which resolves with an ES Module.
This plugin will convert that to an async `sap.ui.require` wrapped in a Promise.
The resolved object will be a ES module or pseudo ES module having a 'default' property on it to reference the module by, to match the format used by `import()`. If the module is not a real ES module and already has a default property, the promise will be rejected with an error.
The resolved object will be a ES module or pseudo ES module having a 'default' property on it to reference the module by, to match the format used by `import()`.
If the module is not a real ES module and already has a default property, the promise will be rejected with an error.
For JavaScript projects, this syntax doesn't provide much advantage over a small utility function and has the downside of not working if your module has a 'default' property. The main advantage of this syntax is with TypeScript projects, where the TypeScript compiler will know the type of the imported module, so there his no need to define a separate interface for it.
For JavaScript projects, this syntax doesn't provide much advantage over a small utility function and has the downside of not working if your module has a 'default' property.
The main advantage of this syntax is with TypeScript projects, where the TypeScript compiler will know the type of the imported module, so there is no need to define a separate interface for it.
Also note that while the ES dynamic import specification requires a relative path, `sap.ui.require` works with absolute paths using a module prefix.
Expand Down Expand Up @@ -599,6 +602,7 @@ const MyControl = SAPClass.extend('MyControl', {
### Imports
- `noImportInteropPrefixes` (Default `['sap/']`) A list of import path prefixes which never need an import inter-opt.
- `modulesMap` (Default {}) Mapping for an import's path. Accepts object or function.
### Exports
Expand Down Expand Up @@ -661,7 +665,7 @@ Some preload plugins:
- Export interop control
- Others..
Contribute
## Contribute
Please do! Open an issue, or file a PR.
Issues also welcome for feature requests.
Expand Down
28 changes: 28 additions & 0 deletions packages/plugin/__test__/__snapshots__/test.js.snap
Expand Up @@ -1041,6 +1041,34 @@ exports[`imports import-dynamic.js 1`] = `
});"
`;
exports[`imports import-modules-map.js 1`] = `
"sap.ui.define([\\"./vendor/browser-polyfill\\"], function (__X) {
function _interopRequireDefault(obj) {
return obj && obj.__esModule && typeof obj.default !== \\"undefined\\" ? obj.default : obj;
}
const X = _interopRequireDefault(__X);
const Named1 = __X[\\"Named1\\"];
const Named2 = __X[\\"Named2\\"];
const X2 = __X;
});"
`;
exports[`imports import-modules-map-fn.js 1`] = `
"sap.ui.define([\\"./vendor/browser-polyfill\\"], function (__X) {
function _interopRequireDefault(obj) {
return obj && obj.__esModule && typeof obj.default !== \\"undefined\\" ? obj.default : obj;
}
const X = _interopRequireDefault(__X);
const Named1 = __X[\\"Named1\\"];
const Named2 = __X[\\"Named2\\"];
const X2 = __X;
});"
`;
exports[`imports import-multiple.js 1`] = `
"sap.ui.define([\\"./../a/b\\", \\"path/having-dash\\", \\"A\\", \\"BC\\", \\"DEF\\", \\"G\\", \\"HI\\"], function (____a_b, __path_having_dash, __A, __BC, __D, G, __H) {
function _interopRequireDefault(obj) {
Expand Down
@@ -0,0 +1,4 @@
import "@babel/polyfill";
import X, { Named1 } from "@babel/polyfill";
import { Named2 } from "@babel/polyfill";
import * as X2 from "@babel/polyfill";
@@ -0,0 +1,4 @@
import "@babel/polyfill";
import X, { Named1 } from "@babel/polyfill";
import { Named2 } from "@babel/polyfill";
import * as X2 from "@babel/polyfill";
11 changes: 11 additions & 0 deletions packages/plugin/__test__/options.js
@@ -1,5 +1,8 @@
import { parse } from "path";

/**
* Provides the ability to set options per test file or directory.
*/
const Options = {
default: {
namespacePrefix: undefined,
Expand Down Expand Up @@ -36,6 +39,14 @@ const Options = {
"class-convert-constructor-keep-annot.controller": {
moveControllerConstructorToOnInit: true,
},
"import-modules-map": {
modulesMap: {
["@babel/polyfill"]: "./vendor/browser-polyfill",
},
},
"import-modules-map-fn": {
modulesMap: src => Options.files["import-modules-map"].modulesMap[src],
},
},
dirs: {
"min-wrap": {
Expand Down
10 changes: 8 additions & 2 deletions packages/plugin/src/index.js
Expand Up @@ -98,11 +98,17 @@ module.exports = () => {

const name = cleanImportSource(src); // default to the src for import without named var

const { modulesMap = {} } = opts;
const mappedSrc =
(typeof modulesMap === "function"
? modulesMap(src)
: modulesMap[src]) || src;

// Note that existingImport may get mutated if there are multiple import lines from the same module.
const existingImport = this.imports.find(imp => imp.src === src);
const existingImport = this.imports.find(imp => imp.src === mappedSrc);

const imp = existingImport || {
src, // url
src: mappedSrc, // url
name,
// isLib, // for future use separating UI5 imports from npm/webpack imports
// isUi5Src, // not used yet
Expand Down

0 comments on commit 661e562

Please sign in to comment.