Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Lazy Import: Allow local paths as an option when importing #23751

Merged
merged 2 commits into from
Nov 5, 2020
Merged
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
19 changes: 2 additions & 17 deletions packages/is-shallow-equal/benchmark/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,23 +26,8 @@ Promise.all( [
lazyImport( 'shallow-equal@^1.2.1' ),
lazyImport( 'is-equal-shallow@^0.1.3' ),
lazyImport( 'shallow-equals@^1.0.0' ),
new Promise( async ( resolve ) => {
try {
await lazyImport( 'fbjs@^1.0.0' );
} catch ( error ) {
// The fjbs package throws an error when imported directly. Since
// lazyImport will automatically require the module for the resolved
// value, anticipate and disregard the error, as long as it's the
// expected error message.
if (
'The fbjs package should not be required without a full path.' !==
error.message
) {
throw error;
}
}

resolve( require( 'fbjs/lib/shallowEqual' ) );
lazyImport( 'fbjs@^1.0.0', {
localPath: './lib/shallowEqual',
} ),
] ).then(
( [
Expand Down
6 changes: 5 additions & 1 deletion packages/lazy-import/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

## Unreleased

### New Feature

- Allow local paths as an option when trying to import a specific file from the package ([#23751](https://github.com/WordPress/gutenberg/pull/23751)).

## 1.0.0 (2020-06-15)

- Initial release.
- Initial release.
16 changes: 13 additions & 3 deletions packages/lazy-import/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,10 @@ function onInstall() {
console.log( 'Installing…' );
}

lazyImport( 'is-equal-shallow@^0.1.3', { onInstall } ).then( /* ... */ );
lazyImport( 'fbjs@^1.0.0', {
localPath: './lib/shallowEqual',
onInstall,
} ).then(/* ... */);
```

Note that `lazyImport` can throw an error when offline and unable to install the dependency using NPM. You may want to anticipate this and provide remediation steps for a failed install, such as logging a warning messsage:
Expand All @@ -69,10 +72,17 @@ try {

### Options

#### `localPath`

- Type: `string`
- Required: No

Local path pointing to a file or directory that can be used when other script that `main` needs to be imported.

#### `onInstall`

- Type: `Function`
- Required: No
- Type: `Function`
- Required: No

Function to call if and when the module is being installed. Since installation can cause a delay in script execution, this can be useful to output logging information or display a spinner.

Expand Down
14 changes: 8 additions & 6 deletions packages/lazy-import/lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ const { createHash } = require( 'crypto' );
/**
* @typedef WPLazyImportOptions
*
* @property {()=>void} onInstall Callback to invoke when install starts.
* @property {string} [localPath] Path to the local directory or file.
* @property {()=>void} [onInstall] Callback to invoke when install starts.
*/

/**
Expand Down Expand Up @@ -63,6 +64,7 @@ async function install( arg, alias ) {
* @return {Promise<NodeRequire>} Promise resolving to required module.
*/
async function lazyImport( arg, options = {} ) {
const { localPath = '' } = options;
const { rawSpec, name } = npmPackageArg( arg );

if ( ! name ) {
Expand All @@ -77,21 +79,21 @@ async function lazyImport( arg, options = {} ) {
// need to verify both availability and version. Version isn't necessary to
// account for in this first attempt.
try {
return require( localModule );
if ( require.resolve( localModule ) ) {
return require( join( localModule, localPath ) );
}
} catch ( error ) {
if ( error.code !== 'MODULE_NOT_FOUND' ) {
throw error;
}
}

try {
const resolved = require( name );

const { version } = require( join( name, 'package.json' ) );
if ( semver.satisfies( version, rawSpec ) ) {
// Only return with the resolved module if the version is valid per
// the parsed arg. Otherwise, fall through to install stage.
return resolved;
return require( join( name, localPath ) );
}
} catch ( error ) {
if ( error.code !== 'MODULE_NOT_FOUND' ) {
Expand Down Expand Up @@ -133,7 +135,7 @@ async function lazyImport( arg, options = {} ) {
//
// See: https://github.com/WordPress/gutenberg/pull/22684#discussion_r434583858

return require( localModule );
return require( join( localModule, localPath ) );
}

module.exports = lazyImport;