eslint-import-resolver-webpack
Advanced tools
Comparing version
593
index.js
@@ -6,5 +6,4 @@ 'use strict'; | ||
const isEqual = require('lodash/isEqual'); | ||
const find = require('array.prototype.find'); | ||
const interpret = require('interpret'); | ||
const fs = require('fs'); | ||
const existsSync = require('fs').existsSync; | ||
const isCore = require('is-core-module'); | ||
@@ -15,2 +14,5 @@ const resolve = require('resolve/sync'); | ||
const isRegex = require('is-regex'); | ||
const isArray = Array.isArray; | ||
const keys = Object.keys; | ||
const assign = Object.assign; | ||
@@ -21,201 +23,124 @@ const log = require('debug')('eslint-plugin-import:resolver:webpack'); | ||
/** | ||
* Find the full path to 'source', given 'file' as a full reference path. | ||
* | ||
* resolveImport('./foo', '/Users/ben/bar.js') => '/Users/ben/foo.js' | ||
* @param {string} source - the module to resolve; i.e './some-module' | ||
* @param {string} file - the importing file's full path; i.e. '/usr/local/bin/file.js' | ||
* @param {object} settings - the webpack config file name, as well as cwd | ||
* @example | ||
* options: { | ||
* // Path to the webpack config | ||
* config: 'webpack.config.js', | ||
* // Path to be used to determine where to resolve webpack from | ||
* // (may differ from the cwd in some cases) | ||
* cwd: process.cwd() | ||
* } | ||
* @return {string?} the resolved path to source, undefined if not resolved, or null | ||
* if resolved to a non-FS resource (i.e. script tag at page load) | ||
*/ | ||
exports.resolve = function (source, file, settings) { | ||
// strip loaders | ||
const finalBang = source.lastIndexOf('!'); | ||
if (finalBang >= 0) { | ||
source = source.slice(finalBang + 1); | ||
function registerCompiler(moduleDescriptor) { | ||
if (moduleDescriptor) { | ||
if (typeof moduleDescriptor === 'string') { | ||
require(moduleDescriptor); | ||
} else if (!isArray(moduleDescriptor)) { | ||
moduleDescriptor.register(require(moduleDescriptor.module)); | ||
} else { | ||
for (let i = 0; i < moduleDescriptor.length; i++) { | ||
try { | ||
registerCompiler(moduleDescriptor[i]); | ||
break; | ||
} catch (e) { | ||
log('Failed to register compiler for moduleDescriptor[]:', i, moduleDescriptor); | ||
} | ||
} | ||
} | ||
} | ||
} | ||
// strip resource query | ||
const finalQuestionMark = source.lastIndexOf('?'); | ||
if (finalQuestionMark >= 0) { | ||
source = source.slice(0, finalQuestionMark); | ||
} | ||
function findConfigPath(configPath, packageDir) { | ||
const extensions = keys(interpret.extensions).sort(function (a, b) { | ||
return a === '.js' ? -1 : b === '.js' ? 1 : a.length - b.length; | ||
}); | ||
let extension; | ||
let webpackConfig; | ||
const _configPath = settings && settings.config; | ||
/** | ||
* Attempt to set the current working directory. | ||
* If none is passed, default to the `cwd` where the config is located. | ||
*/ | ||
const cwd = settings && settings.cwd; | ||
const configIndex = settings && settings['config-index']; | ||
const env = settings && settings.env; | ||
const argv = settings && typeof settings.argv !== 'undefined' ? settings.argv : {}; | ||
let packageDir; | ||
let configPath = typeof _configPath === 'string' && _configPath.startsWith('.') | ||
? path.resolve(_configPath) | ||
: _configPath; | ||
log('Config path from settings:', configPath); | ||
// see if we've got a config path, a config object, an array of config objects or a config function | ||
if (!configPath || typeof configPath === 'string') { | ||
// see if we've got an absolute path | ||
if (!configPath || !path.isAbsolute(configPath)) { | ||
// if not, find ancestral package.json and use its directory as base for the path | ||
packageDir = findRoot(path.resolve(file)); | ||
if (!packageDir) { throw new Error('package not found above ' + file); } | ||
} | ||
configPath = findConfigPath(configPath, packageDir); | ||
log('Config path resolved to:', configPath); | ||
if (configPath) { | ||
try { | ||
webpackConfig = require(configPath); | ||
} catch (e) { | ||
console.log('Error resolving webpackConfig', e); | ||
throw e; | ||
if (configPath) { | ||
for (let i = extensions.length - 1; i >= 0 && !extension; i--) { | ||
const maybeExtension = extensions[i]; | ||
if (configPath.slice(-maybeExtension.length) === maybeExtension) { | ||
extension = maybeExtension; | ||
} | ||
} else { | ||
log('No config path found relative to', file, '; using {}'); | ||
webpackConfig = {}; | ||
} | ||
if (webpackConfig && webpackConfig.default) { | ||
log('Using ES6 module "default" key instead of module.exports.'); | ||
webpackConfig = webpackConfig.default; | ||
// see if we've got an absolute path | ||
if (!path.isAbsolute(configPath)) { | ||
configPath = path.join(packageDir, configPath); | ||
} | ||
} else { | ||
webpackConfig = configPath; | ||
configPath = null; | ||
} | ||
if (typeof webpackConfig === 'function') { | ||
webpackConfig = webpackConfig(env, argv); | ||
} | ||
if (Array.isArray(webpackConfig)) { | ||
webpackConfig = webpackConfig.map((cfg) => { | ||
if (typeof cfg === 'function') { | ||
return cfg(env, argv); | ||
for (let i = 0; i < extensions.length && !extension; i++) { | ||
const maybeExtension = extensions[i]; | ||
const maybePath = path.resolve( | ||
path.join(packageDir, 'webpack.config' + maybeExtension) | ||
); | ||
if (existsSync(maybePath)) { | ||
configPath = maybePath; | ||
extension = maybeExtension; | ||
} | ||
return cfg; | ||
}); | ||
if (typeof configIndex !== 'undefined' && webpackConfig.length > configIndex) { | ||
webpackConfig = webpackConfig[configIndex]; | ||
} else { | ||
webpackConfig = find(webpackConfig, function findFirstWithResolve(config) { | ||
return !!config.resolve; | ||
}); | ||
} | ||
} | ||
if (typeof webpackConfig.then === 'function') { | ||
webpackConfig = {}; | ||
registerCompiler(interpret.extensions[extension]); | ||
return configPath; | ||
} | ||
console.warn('Webpack config returns a `Promise`; that signature is not supported at the moment. Using empty object instead.'); | ||
} | ||
function findExternal(source, externals, context, resolveSync) { | ||
if (!externals) { return false; } | ||
if (webpackConfig == null) { | ||
webpackConfig = {}; | ||
// string match | ||
if (typeof externals === 'string') { return source === externals; } | ||
console.warn('No webpack configuration with a "resolve" field found. Using empty object instead.'); | ||
// array: recurse | ||
if (isArray(externals)) { | ||
return externals.some(function (e) { return findExternal(source, e, context, resolveSync); }); | ||
} | ||
log('Using config: ', webpackConfig); | ||
const resolveSync = getResolveSync(configPath, webpackConfig, cwd); | ||
// externals | ||
if (findExternal(source, webpackConfig.externals, path.dirname(file), resolveSync)) { | ||
return { found: true, path: null }; | ||
if (isRegex(externals)) { | ||
return externals.test(source); | ||
} | ||
// otherwise, resolve "normally" | ||
try { | ||
return { found: true, path: resolveSync(path.dirname(file), source) }; | ||
} catch (err) { | ||
if (isCore(source)) { | ||
return { found: true, path: null }; | ||
if (typeof externals === 'function') { | ||
let functionExternalFound = false; | ||
const callback = function (err, value) { | ||
if (err) { | ||
functionExternalFound = false; | ||
} else { | ||
functionExternalFound = findExternal(source, value, context, resolveSync); | ||
} | ||
}; | ||
// - for prior webpack 5, 'externals function' uses 3 arguments | ||
// - for webpack 5, the count of arguments is less than 3 | ||
if (externals.length === 3) { | ||
externals.call(null, context, source, callback); | ||
} else { | ||
const ctx = { | ||
context, | ||
request: source, | ||
contextInfo: { | ||
issuer: '', | ||
issuerLayer: null, | ||
compiler: '', | ||
}, | ||
getResolve: () => (resolveContext, requestToResolve, cb) => { | ||
if (cb) { | ||
try { | ||
cb(null, resolveSync(resolveContext, requestToResolve)); | ||
} catch (e) { | ||
cb(e); | ||
} | ||
} else { | ||
log('getResolve without callback not supported'); | ||
return Promise.reject(new Error('Not supported')); | ||
} | ||
}, | ||
}; | ||
const result = externals.call(null, ctx, callback); | ||
// todo handling Promise object (using synchronous-promise package?) | ||
if (result && typeof result.then === 'function') { | ||
log('Asynchronous functions for externals not supported'); | ||
} | ||
} | ||
log('Error during module resolution:', err); | ||
return { found: false }; | ||
return functionExternalFound; | ||
} | ||
}; | ||
const MAX_CACHE = 10; | ||
const _cache = []; | ||
function getResolveSync(configPath, webpackConfig, cwd) { | ||
const cacheKey = { configPath, webpackConfig }; | ||
let cached = find(_cache, function (entry) { return isEqual(entry.key, cacheKey); }); | ||
if (!cached) { | ||
cached = { | ||
key: cacheKey, | ||
value: createResolveSync(configPath, webpackConfig, cwd), | ||
}; | ||
// put in front and pop last item | ||
if (_cache.unshift(cached) > MAX_CACHE) { | ||
_cache.pop(); | ||
// else, vanilla object | ||
for (const key in externals) { | ||
if (hasOwn(externals, key) && source === key) { | ||
return true; | ||
} | ||
} | ||
return cached.value; | ||
return false; | ||
} | ||
function createResolveSync(configPath, webpackConfig, cwd) { | ||
let webpackRequire; | ||
let basedir = null; | ||
if (typeof configPath === 'string') { | ||
// This can be changed via the settings passed in when defining the resolver | ||
basedir = cwd || path.dirname(configPath); | ||
log(`Attempting to load webpack path from ${basedir}`); | ||
} | ||
try { | ||
// Attempt to resolve webpack from the given `basedir` | ||
const webpackFilename = resolve('webpack', { basedir, preserveSymlinks: false }); | ||
const webpackResolveOpts = { basedir: path.dirname(webpackFilename), preserveSymlinks: false }; | ||
webpackRequire = function (id) { | ||
return require(resolve(id, webpackResolveOpts)); | ||
}; | ||
} catch (e) { | ||
// Something has gone wrong (or we're in a test). Use our own bundled | ||
// enhanced-resolve. | ||
log('Using bundled enhanced-resolve.'); | ||
webpackRequire = require; | ||
} | ||
const enhancedResolvePackage = webpackRequire('enhanced-resolve/package.json'); | ||
const enhancedResolveVersion = enhancedResolvePackage.version; | ||
log('enhanced-resolve version:', enhancedResolveVersion); | ||
const resolveConfig = webpackConfig.resolve || {}; | ||
if (semver.major(enhancedResolveVersion) >= 2) { | ||
return createWebpack2ResolveSync(webpackRequire, resolveConfig); | ||
} | ||
return createWebpack1ResolveSync(webpackRequire, resolveConfig, webpackConfig.plugins); | ||
} | ||
/** | ||
@@ -237,3 +162,3 @@ * webpack 2 defaults: | ||
return EnhancedResolve.create.sync(Object.assign({}, webpack2DefaultResolveConfig, resolveConfig)); | ||
return EnhancedResolve.create.sync(assign({}, webpack2DefaultResolveConfig, resolveConfig)); | ||
} | ||
@@ -243,8 +168,30 @@ | ||
* webpack 1 defaults: https://webpack.github.io/docs/configuration.html#resolve-packagemains | ||
* @type {Array} | ||
* @type {string[]} | ||
*/ | ||
const webpack1DefaultMains = [ | ||
'webpack', 'browser', 'web', 'browserify', ['jam', 'main'], 'main', | ||
'webpack', | ||
'browser', | ||
'web', | ||
'browserify', | ||
['jam', 'main'], | ||
'main', | ||
]; | ||
/* eslint-disable */ | ||
// from https://github.com/webpack/webpack/blob/v1.13.0/lib/WebpackOptionsApply.js#L365 | ||
function makeRootPlugin(ModulesInRootPlugin, name, root) { | ||
if (typeof root === 'string') { | ||
return new ModulesInRootPlugin(name, root); | ||
} | ||
if (isArray(root)) { | ||
return function () { | ||
root.forEach(function (root) { | ||
this.apply(new ModulesInRootPlugin(name, root)); | ||
}, this); | ||
}; | ||
} | ||
return function () {}; | ||
} | ||
/* eslint-enable */ | ||
// adapted from tests & | ||
@@ -299,3 +246,3 @@ // https://github.com/webpack/webpack/blob/v1.13.0/lib/WebpackOptionsApply.js#L322 | ||
&& plugin.constructor.name === 'ResolverPlugin' | ||
&& Array.isArray(plugin.plugins) | ||
&& isArray(plugin.plugins) | ||
) { | ||
@@ -314,141 +261,167 @@ resolvePlugins.push.apply(resolvePlugins, plugin.plugins); | ||
/* eslint-disable */ | ||
// from https://github.com/webpack/webpack/blob/v1.13.0/lib/WebpackOptionsApply.js#L365 | ||
function makeRootPlugin(ModulesInRootPlugin, name, root) { | ||
if (typeof root === 'string') { | ||
return new ModulesInRootPlugin(name, root); | ||
} else if (Array.isArray(root)) { | ||
return function() { | ||
root.forEach(function (root) { | ||
this.apply(new ModulesInRootPlugin(name, root)); | ||
}, this); | ||
function createResolveSync(configPath, webpackConfig, cwd) { | ||
let webpackRequire; | ||
let basedir = null; | ||
if (typeof configPath === 'string') { | ||
// This can be changed via the settings passed in when defining the resolver | ||
basedir = cwd || path.dirname(configPath); | ||
log(`Attempting to load webpack path from ${basedir}`); | ||
} | ||
try { | ||
// Attempt to resolve webpack from the given `basedir` | ||
const webpackFilename = resolve('webpack', { basedir, preserveSymlinks: false }); | ||
const webpackResolveOpts = { basedir: path.dirname(webpackFilename), preserveSymlinks: false }; | ||
webpackRequire = function (id) { | ||
return require(resolve(id, webpackResolveOpts)); | ||
}; | ||
} catch (e) { | ||
// Something has gone wrong (or we're in a test). Use our own bundled | ||
// enhanced-resolve. | ||
log('Using bundled enhanced-resolve.'); | ||
webpackRequire = require; | ||
} | ||
return function () {}; | ||
} | ||
/* eslint-enable */ | ||
function findExternal(source, externals, context, resolveSync) { | ||
if (!externals) { return false; } | ||
const enhancedResolvePackage = webpackRequire('enhanced-resolve/package.json'); | ||
const enhancedResolveVersion = enhancedResolvePackage.version; | ||
log('enhanced-resolve version:', enhancedResolveVersion); | ||
// string match | ||
if (typeof externals === 'string') { return source === externals; } | ||
const resolveConfig = webpackConfig.resolve || {}; | ||
// array: recurse | ||
if (Array.isArray(externals)) { | ||
return externals.some(function (e) { return findExternal(source, e, context, resolveSync); }); | ||
if (semver.major(enhancedResolveVersion) >= 2) { | ||
return createWebpack2ResolveSync(webpackRequire, resolveConfig); | ||
} | ||
if (isRegex(externals)) { | ||
return externals.test(source); | ||
} | ||
return createWebpack1ResolveSync(webpackRequire, resolveConfig, webpackConfig.plugins); | ||
} | ||
if (typeof externals === 'function') { | ||
let functionExternalFound = false; | ||
const callback = function (err, value) { | ||
if (err) { | ||
functionExternalFound = false; | ||
} else { | ||
functionExternalFound = findExternal(source, value, context, resolveSync); | ||
} | ||
}; | ||
// - for prior webpack 5, 'externals function' uses 3 arguments | ||
// - for webpack 5, the count of arguments is less than 3 | ||
if (externals.length === 3) { | ||
externals.call(null, context, source, callback); | ||
} else { | ||
const ctx = { | ||
context, | ||
request: source, | ||
contextInfo: { | ||
issuer: '', | ||
issuerLayer: null, | ||
compiler: '', | ||
}, | ||
getResolve: () => (resolveContext, requestToResolve, cb) => { | ||
if (cb) { | ||
try { | ||
cb(null, resolveSync(resolveContext, requestToResolve)); | ||
} catch (e) { | ||
cb(e); | ||
} | ||
} else { | ||
log('getResolve without callback not supported'); | ||
return Promise.reject(new Error('Not supported')); | ||
} | ||
}, | ||
}; | ||
const result = externals.call(null, ctx, callback); | ||
// todo handling Promise object (using synchronous-promise package?) | ||
if (result && typeof result.then === 'function') { | ||
log('Asynchronous functions for externals not supported'); | ||
} | ||
const MAX_CACHE = 10; | ||
const _cache = []; | ||
function getResolveSync(configPath, webpackConfig, cwd) { | ||
const cacheKey = { configPath, webpackConfig }; | ||
for (let i = 0; i < _cache.length; i++) { | ||
if (isEqual(_cache[i].key, cacheKey)) { | ||
return _cache[i].value; | ||
} | ||
return functionExternalFound; | ||
} | ||
// else, vanilla object | ||
for (const key in externals) { | ||
if (!hasOwn(externals, key)) { continue; } | ||
if (source === key) { return true; } | ||
const cached = { | ||
key: cacheKey, | ||
value: createResolveSync(configPath, webpackConfig, cwd), | ||
}; | ||
// put in front and pop last item | ||
if (_cache.unshift(cached) > MAX_CACHE) { | ||
_cache.pop(); | ||
} | ||
return false; | ||
return cached.value; | ||
} | ||
function findConfigPath(configPath, packageDir) { | ||
const extensions = Object.keys(interpret.extensions).sort(function (a, b) { | ||
return a === '.js' ? -1 : b === '.js' ? 1 : a.length - b.length; | ||
}); | ||
let extension; | ||
/** | ||
* Find the full path to 'source', given 'file' as a full reference path. | ||
* | ||
* resolveImport('./foo', '/Users/ben/bar.js') => '/Users/ben/foo.js' | ||
* @param {string} source - the module to resolve; i.e './some-module' | ||
* @param {string} file - the importing file's full path; i.e. '/usr/local/bin/file.js' | ||
* @param {object} settings - the webpack config file name, as well as cwd | ||
* @example | ||
* options: { | ||
* // Path to the webpack config | ||
* config: 'webpack.config.js', | ||
* // Path to be used to determine where to resolve webpack from | ||
* // (may differ from the cwd in some cases) | ||
* cwd: process.cwd() | ||
* } | ||
* @return {string?} the resolved path to source, undefined if not resolved, or null | ||
* if resolved to a non-FS resource (i.e. script tag at page load) | ||
*/ | ||
exports.resolve = function (source, file, settings) { | ||
if (configPath) { | ||
// extensions is not reused below, so safe to mutate it here. | ||
extensions.reverse(); | ||
extensions.forEach(function (maybeExtension) { | ||
if (extension) { | ||
return; | ||
} | ||
// strip loaders | ||
const finalBang = source.lastIndexOf('!'); | ||
if (finalBang >= 0) { | ||
source = source.slice(finalBang + 1); | ||
} | ||
if (configPath.substr(-maybeExtension.length) === maybeExtension) { | ||
extension = maybeExtension; | ||
} | ||
}); | ||
// strip resource query | ||
const finalQuestionMark = source.lastIndexOf('?'); | ||
if (finalQuestionMark >= 0) { | ||
source = source.slice(0, finalQuestionMark); | ||
} | ||
let webpackConfig; | ||
const _configPath = settings && settings.config; | ||
/** | ||
* Attempt to set the current working directory. | ||
* If none is passed, default to the `cwd` where the config is located. | ||
*/ | ||
const cwd = settings && settings.cwd; | ||
const configIndex = settings && settings['config-index']; | ||
const env = settings && settings.env; | ||
const argv = settings && typeof settings.argv !== 'undefined' ? settings.argv : {}; | ||
let packageDir; | ||
let configPath = typeof _configPath === 'string' && _configPath.startsWith('.') | ||
? path.resolve(_configPath) | ||
: _configPath; | ||
log('Config path from settings:', configPath); | ||
// see if we've got a config path, a config object, an array of config objects or a config function | ||
if (!configPath || typeof configPath === 'string') { | ||
// see if we've got an absolute path | ||
if (!path.isAbsolute(configPath)) { | ||
configPath = path.join(packageDir, configPath); | ||
if (!configPath || !path.isAbsolute(configPath)) { | ||
// if not, find ancestral package.json and use its directory as base for the path | ||
packageDir = findRoot(path.resolve(file)); | ||
if (!packageDir) { throw new Error('package not found above ' + file); } | ||
} | ||
configPath = findConfigPath(configPath, packageDir); | ||
log('Config path resolved to:', configPath); | ||
if (configPath) { | ||
try { | ||
webpackConfig = require(configPath); | ||
} catch (e) { | ||
console.log('Error resolving webpackConfig', e); | ||
throw e; | ||
} | ||
} else { | ||
log('No config path found relative to', file, '; using {}'); | ||
webpackConfig = {}; | ||
} | ||
if (webpackConfig && webpackConfig.default) { | ||
log('Using ES6 module "default" key instead of module.exports.'); | ||
webpackConfig = webpackConfig.default; | ||
} | ||
} else { | ||
extensions.forEach(function (maybeExtension) { | ||
if (extension) { | ||
return; | ||
webpackConfig = configPath; | ||
configPath = null; | ||
} | ||
if (typeof webpackConfig === 'function') { | ||
webpackConfig = webpackConfig(env, argv); | ||
} | ||
if (isArray(webpackConfig)) { | ||
webpackConfig = webpackConfig.map((cfg) => { | ||
if (typeof cfg === 'function') { | ||
return cfg(env, argv); | ||
} | ||
const maybePath = path.resolve( | ||
path.join(packageDir, 'webpack.config' + maybeExtension) | ||
); | ||
if (fs.existsSync(maybePath)) { | ||
configPath = maybePath; | ||
extension = maybeExtension; | ||
} | ||
return cfg; | ||
}); | ||
} | ||
registerCompiler(interpret.extensions[extension]); | ||
return configPath; | ||
} | ||
function registerCompiler(moduleDescriptor) { | ||
if (moduleDescriptor) { | ||
if (typeof moduleDescriptor === 'string') { | ||
require(moduleDescriptor); | ||
} else if (!Array.isArray(moduleDescriptor)) { | ||
moduleDescriptor.register(require(moduleDescriptor.module)); | ||
if (typeof configIndex !== 'undefined' && webpackConfig.length > configIndex) { | ||
webpackConfig = webpackConfig[configIndex]; | ||
} else { | ||
for (let i = 0; i < moduleDescriptor.length; i++) { | ||
try { | ||
registerCompiler(moduleDescriptor[i]); | ||
for (let i = 0; i < webpackConfig.length; i++) { | ||
if (webpackConfig[i].resolve) { | ||
webpackConfig = webpackConfig[i]; | ||
break; | ||
} catch (e) { | ||
log('Failed to register compiler for moduleDescriptor[]:', i, moduleDescriptor); | ||
} | ||
@@ -458,2 +431,36 @@ } | ||
} | ||
} | ||
if (typeof webpackConfig.then === 'function') { | ||
webpackConfig = {}; | ||
console.warn('Webpack config returns a `Promise`; that signature is not supported at the moment. Using empty object instead.'); | ||
} | ||
if (webpackConfig == null) { | ||
webpackConfig = {}; | ||
console.warn('No webpack configuration with a "resolve" field found. Using empty object instead.'); | ||
} | ||
log('Using config: ', webpackConfig); | ||
const resolveSync = getResolveSync(configPath, webpackConfig, cwd); | ||
// externals | ||
if (findExternal(source, webpackConfig.externals, path.dirname(file), resolveSync)) { | ||
return { found: true, path: null }; | ||
} | ||
// otherwise, resolve "normally" | ||
try { | ||
return { found: true, path: resolveSync(path.dirname(file), source) }; | ||
} catch (err) { | ||
if (isCore(source)) { | ||
return { found: true, path: null }; | ||
} | ||
log('Error during module resolution:', err); | ||
return { found: false }; | ||
} | ||
}; |
{ | ||
"name": "eslint-import-resolver-webpack", | ||
"version": "0.13.8", | ||
"version": "0.13.9", | ||
"description": "Resolve paths to dependencies, given a webpack.config.js. Plugin for eslint-plugin-import.", | ||
@@ -17,3 +17,4 @@ "main": "index.js", | ||
"type": "git", | ||
"url": "git+https://github.com/import-js/eslint-plugin-import.git" | ||
"url": "git+https://github.com/import-js/eslint-plugin-import.git", | ||
"directory": "resolvers/webpack" | ||
}, | ||
@@ -34,3 +35,2 @@ "keywords": [ | ||
"dependencies": { | ||
"array.prototype.find": "^2.2.2", | ||
"debug": "^3.2.7", | ||
@@ -37,0 +37,0 @@ "enhanced-resolve": "^0.9.1", |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
12
-7.69%402
2.03%20221
-0.02%1
Infinity%+ Added
+ Added
+ Added
+ Added
+ Added
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed