Skip to content

Commit

Permalink
Lazy Import: Allow local paths as an opton when importing
Browse files Browse the repository at this point in the history
  • Loading branch information
gziolo committed Jul 7, 2020
1 parent e6a7702 commit bfce27e
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 26 deletions.
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
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;

0 comments on commit bfce27e

Please sign in to comment.