rollup-plugin-node-resolve
Advanced tools
+100
| import {Plugin} from 'rollup'; | ||
| import {AsyncOpts} from 'resolve'; | ||
| export interface Options { | ||
| /** | ||
| * the fields to scan in a package.json to determine the entry point | ||
| * if this list contains "browser", overrides specified in "pkg.browser" | ||
| * will be used | ||
| * @default ['module', 'main'] | ||
| */ | ||
| mainFields?: ReadonlyArray<string>; | ||
| /** | ||
| * @deprecated use "mainFields" instead | ||
| * use "module" field for ES6 module if possible | ||
| * @default true | ||
| */ | ||
| module?: boolean; | ||
| /** | ||
| * @deprecated use "mainFields" instead | ||
| * use "jsnext:main" if possible | ||
| * legacy field pointing to ES6 module in third-party libraries, | ||
| * deprecated in favor of "pkg.module": | ||
| * - see: https://github.com/rollup/rollup/wiki/pkg.module | ||
| * @default false | ||
| */ | ||
| jsnext?: boolean; | ||
| /** | ||
| * @deprecated use "mainFields" instead | ||
| * use "main" field or index.js, even if it's not an ES6 module | ||
| * (needs to be converted from CommonJS to ES6) | ||
| * – see https://github.com/rollup/rollup-plugin-commonjs | ||
| * @default true | ||
| */ | ||
| main?: boolean; | ||
| /** | ||
| * some package.json files have a "browser" field which specifies | ||
| * alternative files to load for people bundling for the browser. If | ||
| * that's you, either use this option or add "browser" to the | ||
| * "mainfields" option, otherwise pkg.browser will be ignored | ||
| * @default false | ||
| */ | ||
| browser?: boolean; | ||
| /** | ||
| * not all files you want to resolve are .js files | ||
| * @default [ '.mjs', '.js', '.json', '.node' ] | ||
| */ | ||
| extensions?: ReadonlyArray<string>; | ||
| /** | ||
| * whether to prefer built-in modules (e.g. `fs`, `path`) or | ||
| * local ones with the same names | ||
| * @default true | ||
| */ | ||
| preferBuiltins?: boolean; | ||
| /** | ||
| * Lock the module search in this path (like a chroot). Module defined | ||
| * outside this path will be marked as external | ||
| * @default '/' | ||
| */ | ||
| jail?: string; | ||
| /** | ||
| * Set to an array of strings and/or regexps to lock the module search | ||
| * to modules that match at least one entry. Modules not matching any | ||
| * entry will be marked as external | ||
| * @default null | ||
| */ | ||
| only?: ReadonlyArray<string | RegExp> | null; | ||
| /** | ||
| * If true, inspect resolved files to check that they are | ||
| * ES2015 modules | ||
| * @default false | ||
| */ | ||
| modulesOnly?: boolean; | ||
| /** | ||
| * Force resolving for these modules to root's node_modules that helps | ||
| * to prevent bundling the same package multiple times if package is | ||
| * imported from dependencies. | ||
| */ | ||
| dedupe?: string[]; | ||
| /** | ||
| * Any additional options that should be passed through | ||
| * to node-resolve | ||
| */ | ||
| customResolveOptions?: AsyncOpts; | ||
| } | ||
| /** | ||
| * Locate modules using the Node resolution algorithm, for using third party modules in node_modules | ||
| */ | ||
| export default function nodeResolve(options?: Options): Plugin; |
+34
-0
| # rollup-plugin-node-resolve changelog | ||
| ## 4.2.4 (2019-05-11) | ||
| * Add note on builtins to Readme ([#215](https://github.com/rollup/rollup-plugin-node-resolve/pull/215) by @keithamus) | ||
| * Add issue templates ([#217](https://github.com/rollup/rollup-plugin-node-resolve/pull/217) by @mecurc) | ||
| * Improve performance by caching `isDir` ([#218](https://github.com/rollup/rollup-plugin-node-resolve/pull/218) by @keithamus) | ||
| ## 4.2.3 (2019-04-11) | ||
| * Fix ordering of jsnext:main when using the jsnext option ([#209](https://github.com/rollup/rollup-plugin-node-resolve/pull/209) by @lukastaegert) | ||
| ## 4.2.2 (2019-04-10) | ||
| * Fix TypeScript typings (rename and export Options interface) ([#206](https://github.com/rollup/rollup-plugin-node-resolve/pull/206) by @Kocal) | ||
| * Fix mainfields typing ([#207](https://github.com/rollup/rollup-plugin-node-resolve/pull/207) by @nicolashenry) | ||
| ## 4.2.1 (2019-04-06) | ||
| * Respect setting the deprecated fields "module", "main", and "jsnext" ([#204](https://github.com/rollup/rollup-plugin-node-resolve/pull/204) by @nick-woodward) | ||
| ## 4.2.0 (2019-04-06) | ||
| * Add new mainfields option ([#182](https://github.com/rollup/rollup-plugin-node-resolve/pull/182) by @keithamus) | ||
| * Added dedupe option to prevent bundling the same package multiple times ([#201](https://github.com/rollup/rollup-plugin-node-resolve/pull/182) by @sormy) | ||
| ## 4.1.0 (2019-04-05) | ||
| * Add TypeScript typings ([#189](https://github.com/rollup/rollup-plugin-node-resolve/pull/189) by @NotWoods) | ||
| * Update dependencies ([#202](https://github.com/rollup/rollup-plugin-node-resolve/pull/202) by @lukastaegert) | ||
| ## 4.0.1 (2019-02-22) | ||
| * Fix issue when external modules are specified in `package.browser` ([#143](https://github.com/rollup/rollup-plugin-node-resolve/pull/143) by @keithamus) | ||
| * Fix `package.browser` mapping issue when `false` is specified ([#183](https://github.com/rollup/rollup-plugin-node-resolve/pull/183) by @allex) | ||
| ## 4.0.0 (2018-12-09) | ||
@@ -4,0 +38,0 @@ |
@@ -16,28 +16,58 @@ 'use strict'; | ||
| var readFileCache = {}; | ||
| var readFileAsync = function (file) { return new Promise(function (fulfil, reject) { return fs.readFile(file, function (err, contents) { return err ? reject(err) : fulfil(contents); }); }); }; | ||
| var statAsync = function (file) { return new Promise(function (fulfil, reject) { return fs.stat(file, function (err, contents) { return err ? reject(err) : fulfil(contents); }); }); }; | ||
| function cachedReadFile (file, cb) { | ||
| if (file in readFileCache === false) { | ||
| readFileCache[file] = readFileAsync(file).catch(function (err) { | ||
| delete readFileCache[file]; | ||
| throw err; | ||
| var cache = function (fn) { | ||
| var cache = new Map(); | ||
| var wrapped = function (param, done) { | ||
| if (cache.has(param) === false) { | ||
| cache.set(param, fn(param).catch(function (err) { | ||
| cache.delete(param); | ||
| throw err; | ||
| })); | ||
| } | ||
| return cache.get(param).then(function (result) { return done(null, result); }, done); | ||
| }; | ||
| wrapped.clear = function () { return cache.clear(); }; | ||
| return wrapped; | ||
| }; | ||
| var ignoreENOENT = function (err) { | ||
| if (err.code === 'ENOENT') { return false; } | ||
| throw err; | ||
| }; | ||
| var readFileCached = cache(readFileAsync); | ||
| var isDirCached = cache(function (file) { return statAsync(file).then(function (stat) { return stat.isDirectory(); }, ignoreENOENT); }); | ||
| var isFileCached = cache(function (file) { return statAsync(file).then(function (stat) { return stat.isFile(); }, ignoreENOENT); }); | ||
| function getMainFields (options) { | ||
| var mainFields; | ||
| if (options.mainFields) { | ||
| if ('module' in options || 'main' in options || 'jsnext' in options) { | ||
| throw new Error("node-resolve: do not use deprecated 'module', 'main', 'jsnext' options with 'mainFields'"); | ||
| } | ||
| mainFields = options.mainFields; | ||
| } else { | ||
| mainFields = []; | ||
| [['module', 'module', true], ['jsnext', 'jsnext:main', false], ['main', 'main', true]].forEach(function (ref) { | ||
| var option = ref[0]; | ||
| var field = ref[1]; | ||
| var defaultIncluded = ref[2]; | ||
| if (option in options) { | ||
| // eslint-disable-next-line no-console | ||
| console.warn(("node-resolve: setting options." + option + " is deprecated, please override options.mainFields instead")); | ||
| if (options[option]) { | ||
| mainFields.push(field); | ||
| } | ||
| } else if (defaultIncluded) { | ||
| mainFields.push(field); | ||
| } | ||
| }); | ||
| } | ||
| readFileCache[file].then(function (contents) { return cb(null, contents); }, cb); | ||
| } | ||
| var isFileCache = {}; | ||
| function cachedIsFile (file, cb) { | ||
| if (file in isFileCache === false) { | ||
| isFileCache[file] = statAsync(file) | ||
| .then( | ||
| function (stat) { return stat.isFile(); }, | ||
| function (err) { | ||
| if (err.code == 'ENOENT') { return false; } | ||
| delete isFileCache[file]; | ||
| throw err; | ||
| }); | ||
| if (options.browser && mainFields.indexOf('browser') === -1) { | ||
| return ['browser'].concat(mainFields); | ||
| } | ||
| isFileCache[file].then(function (contents) { return cb(null, contents); }, cb); | ||
| if ( !mainFields.length ) { | ||
| throw new Error( "Please ensure at least one 'mainFields' value is specified" ); | ||
| } | ||
| return mainFields; | ||
| } | ||
@@ -50,5 +80,5 @@ | ||
| var useModule = options.module !== false; | ||
| var useMain = options.main !== false; | ||
| var useJsnext = options.jsnext === true; | ||
| var mainFields = getMainFields(options); | ||
| var useBrowserOverrides = mainFields.indexOf('browser') !== -1; | ||
| var dedupe = options.dedupe || []; | ||
| var isPreferBuiltinsSet = options.preferBuiltins === true || options.preferBuiltins === false; | ||
@@ -70,6 +100,2 @@ var preferBuiltins = isPreferBuiltinsSet ? options.preferBuiltins : true; | ||
| if ( !useModule && !useMain && !useJsnext ) { | ||
| throw new Error( "At least one of options.module, options.main or options.jsnext must be true" ); | ||
| } | ||
| var preserveSymlinks; | ||
@@ -85,7 +111,8 @@ | ||
| generateBundle: function generateBundle () { | ||
| isFileCache = {}; | ||
| readFileCache = {}; | ||
| readFileCached.clear(); | ||
| isFileCached.clear(); | ||
| isDirCached.clear(); | ||
| }, | ||
| resolveId: function resolveId$$1 ( importee, importer ) { | ||
| resolveId: function resolveId ( importee, importer ) { | ||
| var this$1 = this; | ||
@@ -97,3 +124,8 @@ | ||
| if (options.browser && browserMapCache[importer]) { | ||
| if (dedupe.indexOf(importee) !== -1) { | ||
| importee = path.join(process.cwd(), 'node_modules', importee); | ||
| } | ||
| // https://github.com/defunctzombie/package-browser-field-spec | ||
| if (useBrowserOverrides && browserMapCache[importer]) { | ||
| var resolvedImportee = path.resolve( basedir, importee ); | ||
@@ -109,3 +141,2 @@ var browser = browserMapCache[importer]; | ||
| var parts = importee.split( /[/\\]/ ); | ||
@@ -132,5 +163,8 @@ var id = parts.shift(); | ||
| var pkgRoot = path.dirname( pkgPath ); | ||
| if (options.browser && typeof pkg[ 'browser' ] === 'object') { | ||
| if (useBrowserOverrides && typeof pkg[ 'browser' ] === 'object') { | ||
| packageBrowserField = Object.keys(pkg[ 'browser' ]).reduce(function (browser, key) { | ||
| var resolved = pkg[ 'browser' ][ key ] === false ? false : path.resolve( pkgRoot, pkg[ 'browser' ][ key ] ); | ||
| var resolved = pkg[ 'browser' ][ key ]; | ||
| if (resolved && resolved[0] === '.') { | ||
| resolved = path.resolve( pkgRoot, pkg[ 'browser' ][ key ] ); | ||
| } | ||
| browser[ key ] = resolved; | ||
@@ -151,9 +185,12 @@ if ( key[0] === '.' ) { | ||
| if (options.browser && typeof pkg[ 'browser' ] === 'string') { | ||
| pkg[ 'main' ] = pkg[ 'browser' ]; | ||
| } else if ( useModule && pkg[ 'module' ] ) { | ||
| pkg[ 'main' ] = pkg[ 'module' ]; | ||
| } else if ( useJsnext && pkg[ 'jsnext:main' ] ) { | ||
| pkg[ 'main' ] = pkg[ 'jsnext:main' ]; | ||
| } else if ( ( useJsnext || useModule ) && !useMain ) { | ||
| var overriddenMain = false; | ||
| for ( var i = 0; i < mainFields.length; i++ ) { | ||
| var field = mainFields[i]; | ||
| if ( typeof pkg[ field ] === 'string' ) { | ||
| pkg[ 'main' ] = pkg[ field ]; | ||
| overriddenMain = true; | ||
| break; | ||
| } | ||
| } | ||
| if ( overriddenMain === false && mainFields.indexOf( 'main' ) === -1 ) { | ||
| disregardResult = true; | ||
@@ -163,4 +200,5 @@ } | ||
| }, | ||
| readFile: cachedReadFile, | ||
| isFile: cachedIsFile, | ||
| readFile: readFileCached, | ||
| isFile: isFileCached, | ||
| isDirectory: isDirCached, | ||
| extensions: extensions | ||
@@ -177,6 +215,9 @@ }; | ||
| ) | ||
| .catch(function () { return false; }) | ||
| .then(function (resolved) { | ||
| if (options.browser && packageBrowserField) { | ||
| if (packageBrowserField[ resolved ]) { | ||
| if ( resolved && useBrowserOverrides && packageBrowserField ) { | ||
| if ( packageBrowserField.hasOwnProperty(resolved) ) { | ||
| if (!packageBrowserField[resolved]) { | ||
| browserMapCache[resolved] = packageBrowserField; | ||
| return ES6_BROWSER_EMPTY; | ||
| } | ||
| resolved = packageBrowserField[ resolved ]; | ||
@@ -187,3 +228,3 @@ } | ||
| if ( !disregardResult && resolved !== false ) { | ||
| if ( !disregardResult ) { | ||
| if ( !preserveSymlinks && resolved && fs.existsSync( resolved ) ) { | ||
@@ -212,5 +253,6 @@ resolved = fs.realpathSync( resolved ); | ||
| } else { | ||
| return resolved === false ? null : resolved; | ||
| return resolved; | ||
| } | ||
| }); | ||
| }) | ||
| .catch(function () { return null; }); | ||
| } | ||
@@ -217,0 +259,0 @@ }; |
@@ -1,2 +0,2 @@ | ||
| import { dirname, extname, normalize, resolve, sep } from 'path'; | ||
| import { dirname, join, resolve, normalize, sep, extname } from 'path'; | ||
| import builtins from 'builtin-modules'; | ||
@@ -12,28 +12,58 @@ import resolveId from 'resolve'; | ||
| var readFileCache = {}; | ||
| var readFileAsync = function (file) { return new Promise(function (fulfil, reject) { return fs.readFile(file, function (err, contents) { return err ? reject(err) : fulfil(contents); }); }); }; | ||
| var statAsync = function (file) { return new Promise(function (fulfil, reject) { return fs.stat(file, function (err, contents) { return err ? reject(err) : fulfil(contents); }); }); }; | ||
| function cachedReadFile (file, cb) { | ||
| if (file in readFileCache === false) { | ||
| readFileCache[file] = readFileAsync(file).catch(function (err) { | ||
| delete readFileCache[file]; | ||
| throw err; | ||
| var cache = function (fn) { | ||
| var cache = new Map(); | ||
| var wrapped = function (param, done) { | ||
| if (cache.has(param) === false) { | ||
| cache.set(param, fn(param).catch(function (err) { | ||
| cache.delete(param); | ||
| throw err; | ||
| })); | ||
| } | ||
| return cache.get(param).then(function (result) { return done(null, result); }, done); | ||
| }; | ||
| wrapped.clear = function () { return cache.clear(); }; | ||
| return wrapped; | ||
| }; | ||
| var ignoreENOENT = function (err) { | ||
| if (err.code === 'ENOENT') { return false; } | ||
| throw err; | ||
| }; | ||
| var readFileCached = cache(readFileAsync); | ||
| var isDirCached = cache(function (file) { return statAsync(file).then(function (stat) { return stat.isDirectory(); }, ignoreENOENT); }); | ||
| var isFileCached = cache(function (file) { return statAsync(file).then(function (stat) { return stat.isFile(); }, ignoreENOENT); }); | ||
| function getMainFields (options) { | ||
| var mainFields; | ||
| if (options.mainFields) { | ||
| if ('module' in options || 'main' in options || 'jsnext' in options) { | ||
| throw new Error("node-resolve: do not use deprecated 'module', 'main', 'jsnext' options with 'mainFields'"); | ||
| } | ||
| mainFields = options.mainFields; | ||
| } else { | ||
| mainFields = []; | ||
| [['module', 'module', true], ['jsnext', 'jsnext:main', false], ['main', 'main', true]].forEach(function (ref) { | ||
| var option = ref[0]; | ||
| var field = ref[1]; | ||
| var defaultIncluded = ref[2]; | ||
| if (option in options) { | ||
| // eslint-disable-next-line no-console | ||
| console.warn(("node-resolve: setting options." + option + " is deprecated, please override options.mainFields instead")); | ||
| if (options[option]) { | ||
| mainFields.push(field); | ||
| } | ||
| } else if (defaultIncluded) { | ||
| mainFields.push(field); | ||
| } | ||
| }); | ||
| } | ||
| readFileCache[file].then(function (contents) { return cb(null, contents); }, cb); | ||
| } | ||
| var isFileCache = {}; | ||
| function cachedIsFile (file, cb) { | ||
| if (file in isFileCache === false) { | ||
| isFileCache[file] = statAsync(file) | ||
| .then( | ||
| function (stat) { return stat.isFile(); }, | ||
| function (err) { | ||
| if (err.code == 'ENOENT') { return false; } | ||
| delete isFileCache[file]; | ||
| throw err; | ||
| }); | ||
| if (options.browser && mainFields.indexOf('browser') === -1) { | ||
| return ['browser'].concat(mainFields); | ||
| } | ||
| isFileCache[file].then(function (contents) { return cb(null, contents); }, cb); | ||
| if ( !mainFields.length ) { | ||
| throw new Error( "Please ensure at least one 'mainFields' value is specified" ); | ||
| } | ||
| return mainFields; | ||
| } | ||
@@ -46,5 +76,5 @@ | ||
| var useModule = options.module !== false; | ||
| var useMain = options.main !== false; | ||
| var useJsnext = options.jsnext === true; | ||
| var mainFields = getMainFields(options); | ||
| var useBrowserOverrides = mainFields.indexOf('browser') !== -1; | ||
| var dedupe = options.dedupe || []; | ||
| var isPreferBuiltinsSet = options.preferBuiltins === true || options.preferBuiltins === false; | ||
@@ -66,6 +96,2 @@ var preferBuiltins = isPreferBuiltinsSet ? options.preferBuiltins : true; | ||
| if ( !useModule && !useMain && !useJsnext ) { | ||
| throw new Error( "At least one of options.module, options.main or options.jsnext must be true" ); | ||
| } | ||
| var preserveSymlinks; | ||
@@ -81,7 +107,8 @@ | ||
| generateBundle: function generateBundle () { | ||
| isFileCache = {}; | ||
| readFileCache = {}; | ||
| readFileCached.clear(); | ||
| isFileCached.clear(); | ||
| isDirCached.clear(); | ||
| }, | ||
| resolveId: function resolveId$$1 ( importee, importer ) { | ||
| resolveId: function resolveId ( importee, importer ) { | ||
| var this$1 = this; | ||
@@ -93,3 +120,8 @@ | ||
| if (options.browser && browserMapCache[importer]) { | ||
| if (dedupe.indexOf(importee) !== -1) { | ||
| importee = join(process.cwd(), 'node_modules', importee); | ||
| } | ||
| // https://github.com/defunctzombie/package-browser-field-spec | ||
| if (useBrowserOverrides && browserMapCache[importer]) { | ||
| var resolvedImportee = resolve( basedir, importee ); | ||
@@ -105,3 +137,2 @@ var browser = browserMapCache[importer]; | ||
| var parts = importee.split( /[/\\]/ ); | ||
@@ -128,5 +159,8 @@ var id = parts.shift(); | ||
| var pkgRoot = dirname( pkgPath ); | ||
| if (options.browser && typeof pkg[ 'browser' ] === 'object') { | ||
| if (useBrowserOverrides && typeof pkg[ 'browser' ] === 'object') { | ||
| packageBrowserField = Object.keys(pkg[ 'browser' ]).reduce(function (browser, key) { | ||
| var resolved = pkg[ 'browser' ][ key ] === false ? false : resolve( pkgRoot, pkg[ 'browser' ][ key ] ); | ||
| var resolved = pkg[ 'browser' ][ key ]; | ||
| if (resolved && resolved[0] === '.') { | ||
| resolved = resolve( pkgRoot, pkg[ 'browser' ][ key ] ); | ||
| } | ||
| browser[ key ] = resolved; | ||
@@ -147,9 +181,12 @@ if ( key[0] === '.' ) { | ||
| if (options.browser && typeof pkg[ 'browser' ] === 'string') { | ||
| pkg[ 'main' ] = pkg[ 'browser' ]; | ||
| } else if ( useModule && pkg[ 'module' ] ) { | ||
| pkg[ 'main' ] = pkg[ 'module' ]; | ||
| } else if ( useJsnext && pkg[ 'jsnext:main' ] ) { | ||
| pkg[ 'main' ] = pkg[ 'jsnext:main' ]; | ||
| } else if ( ( useJsnext || useModule ) && !useMain ) { | ||
| var overriddenMain = false; | ||
| for ( var i = 0; i < mainFields.length; i++ ) { | ||
| var field = mainFields[i]; | ||
| if ( typeof pkg[ field ] === 'string' ) { | ||
| pkg[ 'main' ] = pkg[ field ]; | ||
| overriddenMain = true; | ||
| break; | ||
| } | ||
| } | ||
| if ( overriddenMain === false && mainFields.indexOf( 'main' ) === -1 ) { | ||
| disregardResult = true; | ||
@@ -159,4 +196,5 @@ } | ||
| }, | ||
| readFile: cachedReadFile, | ||
| isFile: cachedIsFile, | ||
| readFile: readFileCached, | ||
| isFile: isFileCached, | ||
| isDirectory: isDirCached, | ||
| extensions: extensions | ||
@@ -173,6 +211,9 @@ }; | ||
| ) | ||
| .catch(function () { return false; }) | ||
| .then(function (resolved) { | ||
| if (options.browser && packageBrowserField) { | ||
| if (packageBrowserField[ resolved ]) { | ||
| if ( resolved && useBrowserOverrides && packageBrowserField ) { | ||
| if ( packageBrowserField.hasOwnProperty(resolved) ) { | ||
| if (!packageBrowserField[resolved]) { | ||
| browserMapCache[resolved] = packageBrowserField; | ||
| return ES6_BROWSER_EMPTY; | ||
| } | ||
| resolved = packageBrowserField[ resolved ]; | ||
@@ -183,3 +224,3 @@ } | ||
| if ( !disregardResult && resolved !== false ) { | ||
| if ( !disregardResult ) { | ||
| if ( !preserveSymlinks && resolved && fs.existsSync( resolved ) ) { | ||
@@ -208,5 +249,6 @@ resolved = fs.realpathSync( resolved ); | ||
| } else { | ||
| return resolved === false ? null : resolved; | ||
| return resolved; | ||
| } | ||
| }); | ||
| }) | ||
| .catch(function () { return null; }); | ||
| } | ||
@@ -213,0 +255,0 @@ }; |
+15
-13
| { | ||
| "name": "rollup-plugin-node-resolve", | ||
| "description": "Bundle third-party dependencies in node_modules", | ||
| "version": "4.0.0", | ||
| "version": "4.2.4", | ||
| "devDependencies": { | ||
| "buble": "^0.19.6", | ||
| "es5-ext": "^0.10.46", | ||
| "eslint": "^5.10.0", | ||
| "mocha": "^5.2.0", | ||
| "rollup": "^0.67.4", | ||
| "rollup-plugin-buble": "^0.19.4", | ||
| "rollup-plugin-commonjs": "^9.2.0", | ||
| "buble": "^0.19.7", | ||
| "es5-ext": "^0.10.49", | ||
| "eslint": "^5.16.0", | ||
| "mocha": "^6.1.2", | ||
| "rollup": "^1.9.3", | ||
| "rollup-plugin-buble": "^0.19.6", | ||
| "rollup-plugin-commonjs": "^9.3.4", | ||
| "string-capitalize": "^1.0.1", | ||
| "vlq": "^1.0.0" | ||
| "typescript": "^3.4.3" | ||
| }, | ||
@@ -23,3 +23,3 @@ "main": "dist/rollup-plugin-node-resolve.cjs.js", | ||
| "test": "mocha", | ||
| "posttest": "eslint src test/*.js", | ||
| "posttest": "tsc && eslint src test/*.js", | ||
| "lint": "eslint src", | ||
@@ -31,8 +31,10 @@ "prepublishOnly": "npm test", | ||
| "src", | ||
| "dist" | ||
| "dist", | ||
| "index.d.ts" | ||
| ], | ||
| "dependencies": { | ||
| "builtin-modules": "^3.0.0", | ||
| "@types/resolve": "0.0.8", | ||
| "builtin-modules": "^3.1.0", | ||
| "is-module": "^1.0.0", | ||
| "resolve": "^1.8.1" | ||
| "resolve": "^1.10.0" | ||
| }, | ||
@@ -39,0 +41,0 @@ "repository": "rollup/rollup-plugin-node-resolve", |
+38
-7
@@ -23,10 +23,18 @@ # rollup-plugin-node-resolve | ||
| file: 'bundle.js', | ||
| format: 'iife' | ||
| format: 'iife', | ||
| name: 'MyModule' | ||
| }, | ||
| name: 'MyModule', | ||
| plugins: [ | ||
| resolve({ | ||
| // the fields to scan in a package.json to determine the entry point | ||
| // if this list contains "browser", overrides specified in "pkg.browser" | ||
| // will be used | ||
| mainFields: ['module', 'main'], // Default: ['module', 'main'] | ||
| // DEPRECATED: use "mainFields" instead | ||
| // use "module" field for ES6 module if possible | ||
| module: true, // Default: true | ||
| // DEPRECATED: use "mainFields" instead | ||
| // use "jsnext:main" if possible | ||
@@ -38,11 +46,12 @@ // legacy field pointing to ES6 module in third-party libraries, | ||
| // DEPRECATED: use "mainFields" instead | ||
| // use "main" field or index.js, even if it's not an ES6 module | ||
| // (needs to be converted from CommonJS to ES6 | ||
| // (needs to be converted from CommonJS to ES6) | ||
| // – see https://github.com/rollup/rollup-plugin-commonjs | ||
| main: true, // Default: true | ||
| // some package.json files have a `browser` field which | ||
| // specifies alternative files to load for people bundling | ||
| // for the browser. If that's you, use this option, otherwise | ||
| // pkg.browser will be ignored | ||
| // some package.json files have a "browser" field which specifies | ||
| // alternative files to load for people bundling for the browser. If | ||
| // that's you, either use this option or add "browser" to the | ||
| // "mainfields" option, otherwise pkg.browser will be ignored | ||
| browser: true, // Default: false | ||
@@ -70,2 +79,7 @@ | ||
| // Force resolving for these modules to root's node_modules that helps | ||
| // to prevent bundling the same package multiple times if package is | ||
| // imported from dependencies. | ||
| dedupe: [ 'react', 'react-dom' ], // Default: [] | ||
| // Any additional options that should be passed through | ||
@@ -104,5 +118,22 @@ // to node-resolve | ||
| ## Resolving Built-Ins (like `fs`) | ||
| This plugin won't resolve any builtins (e.g. `fs`). If you need to resolve builtins you can install local modules and set `preferBuiltins` to `false`, or install a plugin like [rollup-plugin-node-builtins](https://github.com/calvinmetcalf/rollup-plugin-node-builtins) which provides stubbed versions of these methods. | ||
| If you want to silence warnings about builtins, you can add the list of builtins to the `externals` option; like so: | ||
| ```js | ||
| import resolve from 'rollup-plugin-node-resolve'; | ||
| import builtins from 'builtin-modules' | ||
| export default ({ | ||
| input: ..., | ||
| plugins: [resolve()], | ||
| externals: builtins, | ||
| output: ... | ||
| }) | ||
| ``` | ||
| ## License | ||
| MIT |
+88
-50
@@ -1,2 +0,2 @@ | ||
| import {dirname, extname, normalize, resolve, sep} from 'path'; | ||
| import {dirname, extname, join, normalize, resolve, sep} from 'path'; | ||
| import builtins from 'builtin-modules'; | ||
@@ -12,28 +12,54 @@ import resolveId from 'resolve'; | ||
| let readFileCache = {}; | ||
| const readFileAsync = file => new Promise((fulfil, reject) => fs.readFile(file, (err, contents) => err ? reject(err) : fulfil(contents))); | ||
| const statAsync = file => new Promise((fulfil, reject) => fs.stat(file, (err, contents) => err ? reject(err) : fulfil(contents))); | ||
| function cachedReadFile (file, cb) { | ||
| if (file in readFileCache === false) { | ||
| readFileCache[file] = readFileAsync(file).catch(err => { | ||
| delete readFileCache[file]; | ||
| throw err; | ||
| const cache = fn => { | ||
| const cache = new Map(); | ||
| const wrapped = (param, done) => { | ||
| if (cache.has(param) === false) { | ||
| cache.set(param, fn(param).catch(err => { | ||
| cache.delete(param); | ||
| throw err; | ||
| })); | ||
| } | ||
| return cache.get(param).then(result => done(null, result), done); | ||
| }; | ||
| wrapped.clear = () => cache.clear(); | ||
| return wrapped; | ||
| }; | ||
| const ignoreENOENT = err => { | ||
| if (err.code === 'ENOENT') return false; | ||
| throw err; | ||
| }; | ||
| const readFileCached = cache(readFileAsync); | ||
| const isDirCached = cache(file => statAsync(file).then(stat => stat.isDirectory(), ignoreENOENT)); | ||
| const isFileCached = cache(file => statAsync(file).then(stat => stat.isFile(), ignoreENOENT)); | ||
| function getMainFields (options) { | ||
| let mainFields; | ||
| if (options.mainFields) { | ||
| if ('module' in options || 'main' in options || 'jsnext' in options) { | ||
| throw new Error(`node-resolve: do not use deprecated 'module', 'main', 'jsnext' options with 'mainFields'`); | ||
| } | ||
| mainFields = options.mainFields; | ||
| } else { | ||
| mainFields = []; | ||
| [['module', 'module', true], ['jsnext', 'jsnext:main', false], ['main', 'main', true]].forEach(([option, field, defaultIncluded]) => { | ||
| if (option in options) { | ||
| // eslint-disable-next-line no-console | ||
| console.warn(`node-resolve: setting options.${option} is deprecated, please override options.mainFields instead`); | ||
| if (options[option]) { | ||
| mainFields.push(field); | ||
| } | ||
| } else if (defaultIncluded) { | ||
| mainFields.push(field); | ||
| } | ||
| }); | ||
| } | ||
| readFileCache[file].then(contents => cb(null, contents), cb); | ||
| } | ||
| let isFileCache = {}; | ||
| function cachedIsFile (file, cb) { | ||
| if (file in isFileCache === false) { | ||
| isFileCache[file] = statAsync(file) | ||
| .then( | ||
| stat => stat.isFile(), | ||
| err => { | ||
| if (err.code == 'ENOENT') return false; | ||
| delete isFileCache[file]; | ||
| throw err; | ||
| }); | ||
| if (options.browser && mainFields.indexOf('browser') === -1) { | ||
| return ['browser'].concat(mainFields); | ||
| } | ||
| isFileCache[file].then(contents => cb(null, contents), cb); | ||
| if ( !mainFields.length ) { | ||
| throw new Error( `Please ensure at least one 'mainFields' value is specified` ); | ||
| } | ||
| return mainFields; | ||
| } | ||
@@ -44,5 +70,5 @@ | ||
| export default function nodeResolve ( options = {} ) { | ||
| const useModule = options.module !== false; | ||
| const useMain = options.main !== false; | ||
| const useJsnext = options.jsnext === true; | ||
| const mainFields = getMainFields(options); | ||
| const useBrowserOverrides = mainFields.indexOf('browser') !== -1; | ||
| const dedupe = options.dedupe || []; | ||
| const isPreferBuiltinsSet = options.preferBuiltins === true || options.preferBuiltins === false; | ||
@@ -64,6 +90,2 @@ const preferBuiltins = isPreferBuiltinsSet ? options.preferBuiltins : true; | ||
| if ( !useModule && !useMain && !useJsnext ) { | ||
| throw new Error( `At least one of options.module, options.main or options.jsnext must be true` ); | ||
| } | ||
| let preserveSymlinks; | ||
@@ -79,4 +101,5 @@ | ||
| generateBundle () { | ||
| isFileCache = {}; | ||
| readFileCache = {}; | ||
| readFileCached.clear(); | ||
| isFileCached.clear(); | ||
| isDirCached.clear(); | ||
| }, | ||
@@ -89,3 +112,8 @@ | ||
| if (options.browser && browserMapCache[importer]) { | ||
| if (dedupe.indexOf(importee) !== -1) { | ||
| importee = join(process.cwd(), 'node_modules', importee); | ||
| } | ||
| // https://github.com/defunctzombie/package-browser-field-spec | ||
| if (useBrowserOverrides && browserMapCache[importer]) { | ||
| const resolvedImportee = resolve( basedir, importee ); | ||
@@ -101,3 +129,2 @@ const browser = browserMapCache[importer]; | ||
| const parts = importee.split( /[/\\]/ ); | ||
@@ -124,5 +151,8 @@ let id = parts.shift(); | ||
| const pkgRoot = dirname( pkgPath ); | ||
| if (options.browser && typeof pkg[ 'browser' ] === 'object') { | ||
| if (useBrowserOverrides && typeof pkg[ 'browser' ] === 'object') { | ||
| packageBrowserField = Object.keys(pkg[ 'browser' ]).reduce((browser, key) => { | ||
| const resolved = pkg[ 'browser' ][ key ] === false ? false : resolve( pkgRoot, pkg[ 'browser' ][ key ] ); | ||
| let resolved = pkg[ 'browser' ][ key ]; | ||
| if (resolved && resolved[0] === '.') { | ||
| resolved = resolve( pkgRoot, pkg[ 'browser' ][ key ] ); | ||
| } | ||
| browser[ key ] = resolved; | ||
@@ -143,9 +173,12 @@ if ( key[0] === '.' ) { | ||
| if (options.browser && typeof pkg[ 'browser' ] === 'string') { | ||
| pkg[ 'main' ] = pkg[ 'browser' ]; | ||
| } else if ( useModule && pkg[ 'module' ] ) { | ||
| pkg[ 'main' ] = pkg[ 'module' ]; | ||
| } else if ( useJsnext && pkg[ 'jsnext:main' ] ) { | ||
| pkg[ 'main' ] = pkg[ 'jsnext:main' ]; | ||
| } else if ( ( useJsnext || useModule ) && !useMain ) { | ||
| let overriddenMain = false; | ||
| for ( let i = 0; i < mainFields.length; i++ ) { | ||
| const field = mainFields[i]; | ||
| if ( typeof pkg[ field ] === 'string' ) { | ||
| pkg[ 'main' ] = pkg[ field ]; | ||
| overriddenMain = true; | ||
| break; | ||
| } | ||
| } | ||
| if ( overriddenMain === false && mainFields.indexOf( 'main' ) === -1 ) { | ||
| disregardResult = true; | ||
@@ -155,4 +188,5 @@ } | ||
| }, | ||
| readFile: cachedReadFile, | ||
| isFile: cachedIsFile, | ||
| readFile: readFileCached, | ||
| isFile: isFileCached, | ||
| isDirectory: isDirCached, | ||
| extensions: extensions | ||
@@ -169,6 +203,9 @@ }; | ||
| ) | ||
| .catch(() => false) | ||
| .then(resolved => { | ||
| if (options.browser && packageBrowserField) { | ||
| if (packageBrowserField[ resolved ]) { | ||
| if ( resolved && useBrowserOverrides && packageBrowserField ) { | ||
| if ( packageBrowserField.hasOwnProperty(resolved) ) { | ||
| if (!packageBrowserField[resolved]) { | ||
| browserMapCache[resolved] = packageBrowserField; | ||
| return ES6_BROWSER_EMPTY; | ||
| } | ||
| resolved = packageBrowserField[ resolved ]; | ||
@@ -179,3 +216,3 @@ } | ||
| if ( !disregardResult && resolved !== false ) { | ||
| if ( !disregardResult ) { | ||
| if ( !preserveSymlinks && resolved && fs.existsSync( resolved ) ) { | ||
@@ -204,7 +241,8 @@ resolved = fs.realpathSync( resolved ); | ||
| } else { | ||
| return resolved === false ? null : resolved; | ||
| return resolved; | ||
| } | ||
| }); | ||
| }) | ||
| .catch(() => null); | ||
| } | ||
| }; | ||
| } |
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Found 1 instance in 1 package
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
39794
35.14%8
14.29%735
40%136
29.52%0
-100%4
33.33%5
25%+ Added
+ Added
+ Added
+ Added
Updated
Updated