next-transpile-modules
Advanced tools
Comparing version 6.3.0 to 6.4.0
{ | ||
"name": "next-transpile-modules", | ||
"version": "6.3.0", | ||
"version": "6.4.0", | ||
"license": "MIT", | ||
@@ -20,6 +20,8 @@ "author": "Pierre de la Martinière <pierre.de.la.martiniere@gmail.com>", | ||
"test:prepare:npm-basic": "npm run build --prefix=src/__tests__/__apps__/npm-basic", | ||
"test:prepare:yarn-worskpaces": "yarn --cwd src/__tests__/__apps__/yarn-workspaces/app run build", | ||
"test:prepare:yarn-workspaces": "yarn --cwd src/__tests__/__apps__/yarn-workspaces/app run build", | ||
"test:prepare:yarn-workspaces-symlinks": "yarn --cwd src/__tests__/__apps__/yarn-workspaces-symlinks/app run build", | ||
"test:prepare:webpack-5": "yarn --cwd src/__tests__/__apps__/webpack-5/app run build", | ||
"test:prepare:webpack-5-symlinks": "yarn --cwd src/__tests__/__apps__/webpack-5-symlinks/app run build", | ||
"test:prepare:pnpm": "npm run build --prefix=src/__tests__/__apps__/pnpm", | ||
"test:prepare": "npm run test:prepare:npm-basic && npm run test:prepare:yarn-worskpaces && npm run test:prepare:webpack-5 && npm run test:prepare:pnpm" | ||
"test:prepare": "npm run test:prepare:npm-basic && npm run test:prepare:yarn-workspaces && npm run test:prepare:yarn-workspaces-symlinks && npm run test:prepare:webpack-5 && npm run test:prepare:webpack-5-symlinks && npm run test:prepare:pnpm" | ||
}, | ||
@@ -26,0 +28,0 @@ "repository": { |
@@ -35,3 +35,3 @@ # Next.js + Transpile `node_modules` | ||
Latest Next.js version tested: **10.0.6**. | ||
Latest Next.js version tested: **10.0.8**. | ||
@@ -56,6 +56,22 @@ ## Installation | ||
- `options` Object (optional) | ||
- `resolveSymlinks` Boolean: Enable symlinks resolution to their real path by Webpack (most of the time, you won't want that) (default to `false`) | ||
- `resolveSymlinks` Boolean: Enable symlinks resolution to their real path by Webpack (default to `false`) | ||
- `debug` Boolean: Display some informative logs in the console (can get noisy!) (default to `false`) | ||
- `__unstable_matcher` (path) => boolean: Custom matcher that will override the default one. Don't use it. | ||
#### Note on `resolveSymlinks` | ||
Node.js resolution is based on the fact that symlinks are resolved. Not resolving them will alter the behavior, but there are some cases where the alternative behavior makes things a lot easier: | ||
- You are using `npm/yarn link` to link packages into node_modules. | ||
- You are using `npm` with `file:` dependencies that live outside of your project directory | ||
- `npm` will create symlinks in this case. Yarn will copy instead. | ||
If this **doesn't** apply to your use case **you should set `resolveSymlinks: true`**, which results in the original behavior and **better performance**. | ||
The following thing will use symlinks, but work great with `resolveSymlinks: true`: | ||
- `pnpm` | ||
- `yarn` workspaces | ||
- `yarn 2` portals | ||
#### Note on Webpack 5 support | ||
@@ -76,5 +92,9 @@ | ||
// next.config.js | ||
const withTM = require('next-transpile-modules')(['somemodule', 'and-another'], { unstable_webpack5: true }); | ||
const withTM = require('next-transpile-modules')(['somemodule', 'and-another']); | ||
module.exports = withTM(); | ||
module.exports = withTM({ | ||
future: { | ||
webpack5: true, | ||
}, | ||
}); | ||
``` | ||
@@ -221,2 +241,10 @@ | ||
### How do I find out which package is causing a runtime exception? | ||
- add `config.optimization.minimize = false;` to you `next.config.js`'s Webpack configuration | ||
- run a production build | ||
- run it on the browser throwing the error | ||
- open the console, jump to the line where it failed | ||
- goes a little bit up in the lines of code, and check the Webpack comments telling you which module is affected | ||
### I have trouble making it work with Lerna | ||
@@ -267,3 +295,7 @@ | ||
module.exports = withTM({ | ||
webpack: (config) => { | ||
webpack: (config, options) => { | ||
+ if (options.isServer) { | ||
+ config.externals = ['react', ...config.externals]; | ||
+ } | ||
+ | ||
+ config.resolve.alias['react'] = path.resolve(__dirname, '.', 'node_modules', 'react'); | ||
@@ -270,0 +302,0 @@ |
/** | ||
* disclaimer: | ||
* | ||
* THIS PLUGIN IS A F*CKING BIG HACK. | ||
* THIS PLUGIN IS A BIG HACK. | ||
* | ||
@@ -24,14 +24,2 @@ * don't even try to reason about the quality of the following lines of code. | ||
/** | ||
* Our own Node.js resolver that can ignore symlinks resolution and can support | ||
* PnP | ||
*/ | ||
const resolve = enhancedResolve.create.sync({ | ||
symlinks: false, | ||
extensions: ['.js', '.jsx', '.ts', '.tsx', '.mjs', '.css', '.scss', '.sass'], | ||
mainFields: ['main', 'module', 'source'], | ||
// Is it right? https://github.com/webpack/enhanced-resolve/issues/283#issuecomment-775162497 | ||
conditionNames: ['require'], | ||
}); | ||
/** | ||
* Check if two regexes are equal | ||
@@ -56,52 +44,2 @@ * Stolen from https://stackoverflow.com/questions/10776600/testing-for-equality-of-regular-expressions | ||
/** | ||
* Return the root path (package.json directory) of a given module | ||
* @param {string} module | ||
* @returns {string} | ||
*/ | ||
const getPackageRootDirectory = (module) => { | ||
let packageDirectory; | ||
let packageRootDirectory; | ||
try { | ||
// Get the module path | ||
packageDirectory = resolve(CWD, module); | ||
if (!packageDirectory) { | ||
throw new Error( | ||
`next-transpile-modules - could not resolve module "${module}". Are you sure the name of the module you are trying to transpile is correct?` | ||
); | ||
} | ||
// Get the location of its package.json | ||
const pkgPath = escalade(packageDirectory, (dir, names) => { | ||
if (names.includes('package.json')) { | ||
return 'package.json'; | ||
} | ||
return false; | ||
}); | ||
if (pkgPath == null) { | ||
throw new Error( | ||
`next-transpile-modules - an error happened when trying to get the root directory of "${module}". Is it missing a package.json?\n${err}` | ||
); | ||
} | ||
packageRootDirectory = path.dirname(pkgPath); | ||
} catch (err) { | ||
throw new Error(`next-transpile-modules - an unexpected error happened when trying to resolve "${module}"\n${err}`); | ||
} | ||
return packageRootDirectory; | ||
}; | ||
/** | ||
* Resolve modules to their real paths | ||
* @param {string[]} modules | ||
* @returns {string[]} | ||
*/ | ||
const generateModulesPaths = (modules) => { | ||
const packagesPaths = modules.map(getPackageRootDirectory); | ||
return packagesPaths; | ||
}; | ||
/** | ||
* Logger for the debug mode | ||
@@ -148,2 +86,3 @@ * @param {boolean} enable enable the logger or not | ||
// IMPROVE ME: false should not be the default for this option | ||
const resolveSymlinks = options.resolveSymlinks || false; | ||
@@ -155,4 +94,58 @@ const isWebpack5 = (nextConfig.future && nextConfig.future.webpack5) || false; | ||
const modulesPaths = generateModulesPaths(modules); | ||
/** | ||
* Our own Node.js resolver that can ignore symlinks resolution and can support | ||
* PnP | ||
*/ | ||
const resolve = enhancedResolve.create.sync({ | ||
symlinks: resolveSymlinks, | ||
extensions: ['.js', '.jsx', '.ts', '.tsx', '.mjs', '.css', '.scss', '.sass'], | ||
mainFields: ['main', 'module', 'source'], | ||
// Is it right? https://github.com/webpack/enhanced-resolve/issues/283#issuecomment-775162497 | ||
conditionNames: ['require'], | ||
}); | ||
/** | ||
* Return the root path (package.json directory) of a given module | ||
* @param {string} module | ||
* @returns {string} | ||
*/ | ||
const getPackageRootDirectory = (module) => { | ||
let packageDirectory; | ||
let packageRootDirectory; | ||
try { | ||
// Get the module path | ||
packageDirectory = resolve(CWD, module); | ||
if (!packageDirectory) { | ||
throw new Error( | ||
`next-transpile-modules - could not resolve module "${module}". Are you sure the name of the module you are trying to transpile is correct?` | ||
); | ||
} | ||
// Get the location of its package.json | ||
const pkgPath = escalade(packageDirectory, (dir, names) => { | ||
if (names.includes('package.json')) { | ||
return 'package.json'; | ||
} | ||
return false; | ||
}); | ||
if (pkgPath == null) { | ||
throw new Error( | ||
`next-transpile-modules - an error happened when trying to get the root directory of "${module}". Is it missing a package.json?\n${err}` | ||
); | ||
} | ||
packageRootDirectory = path.dirname(pkgPath); | ||
} catch (err) { | ||
throw new Error( | ||
`next-transpile-modules - an unexpected error happened when trying to resolve "${module}"\n${err}` | ||
); | ||
} | ||
return packageRootDirectory; | ||
}; | ||
// Resolve modules to their real paths | ||
const modulesPaths = modules.map(getPackageRootDirectory); | ||
if (isWebpack5) logger(`WARNING experimental Webpack 5 support enabled`, true); | ||
@@ -175,28 +168,30 @@ | ||
// Avoid Webpack to resolve transpiled modules path to their real path as | ||
// we want to test modules from node_modules only. If it was enabled, | ||
// modules in node_modules installed via symlink would then not be | ||
// transpiled. | ||
config.resolve.symlinks = resolveSymlinks; | ||
if (resolveSymlinks !== undefined) { | ||
// Avoid Webpack to resolve transpiled modules path to their real path as | ||
// we want to test modules from node_modules only. If it was enabled, | ||
// modules in node_modules installed via symlink would then not be | ||
// transpiled. | ||
config.resolve.symlinks = resolveSymlinks; | ||
} | ||
const hasInclude = (context, request) => { | ||
const test = modulesPaths.some((mod) => { | ||
// If we the code requires/import an absolute path | ||
if (!request.startsWith('.')) { | ||
try { | ||
const moduleDirectory = getPackageRootDirectory(request); | ||
let absolutePath; | ||
// If we the code requires/import an absolute path | ||
if (!request.startsWith('.')) { | ||
try { | ||
const moduleDirectory = getPackageRootDirectory(request); | ||
if (!moduleDirectory) return false; | ||
if (!moduleDirectory) return false; | ||
return moduleDirectory.includes(mod); | ||
} catch (err) { | ||
return false; | ||
} | ||
absolutePath = moduleDirectory; | ||
} catch (err) { | ||
return false; | ||
} | ||
} else { | ||
// Otherwise, for relative imports | ||
return path.resolve(context, request).includes(mod); | ||
absolutePath = path.resolve(context, request); | ||
} | ||
return modulesPaths.some((mod) => { | ||
return absolutePath.startsWith(mod); | ||
}); | ||
return test; | ||
}; | ||
@@ -210,5 +205,12 @@ | ||
if (isWebpack5) { | ||
return async ({ context, request, getResolve }) => { | ||
if (hasInclude(context, request)) return; | ||
return external({ context, request, getResolve }); | ||
return async (options) => { | ||
const externalResult = await external(options); | ||
if (externalResult) { | ||
try { | ||
const resolve = options.getResolve(); | ||
const resolved = await resolve(options.context, options.request); | ||
if (modulesPaths.some((mod) => resolved.startsWith(mod))) return; | ||
} catch (e) {} | ||
} | ||
return externalResult; | ||
}; | ||
@@ -218,3 +220,6 @@ } | ||
return (context, request, cb) => { | ||
return hasInclude(context, request) ? cb() : external(context, request, cb); | ||
external(context, request, (err, external) => { | ||
if (err || !external || !hasInclude(context, request)) return cb(err, external); | ||
cb(); | ||
}); | ||
}; | ||
@@ -232,7 +237,9 @@ }); | ||
// IMPROVE ME: we are losing all the cache on node_modules, which is terrible | ||
// The problem is managedPaths does not allow to isolate specific specific folders | ||
config.snapshot = Object.assign(config.snapshot || {}, { | ||
managedPaths: [], | ||
}); | ||
if (resolveSymlinks === false) { | ||
// IMPROVE ME: we are losing all the cache on node_modules, which is terrible | ||
// The problem is managedPaths does not allow to isolate specific specific folders | ||
config.snapshot = Object.assign(config.snapshot || {}, { | ||
managedPaths: [], | ||
}); | ||
} | ||
} else { | ||
@@ -239,0 +246,0 @@ config.module.rules.push({ |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
25774
255
310