fix(core): resolve webpack loaders with require.resolve() (#3341)
With strict package managers such as pnpm or Yarn PnP, transitive dependencies are *not* hoisted to the root node_modules folder. This means that a webpack config defined within a package like '@nrwl/cypress' cannot resolve loaders like 'ts-loader', unless 'ts-loader' is declared in the workspace's own package.json. This is a problem because the workspace might define a different version of 'ts-loader', incompatible with the version declared by '@nrwl/cypress/package.json'. The workspace should not need to declare a dependency on 'ts-loader' anyway. See also: * https://github.com/pnpm/pnpm/issues/801 * https://github.com/webpack/webpack/issues/5087
This commit is contained in:
parent
24f544100e
commit
d74ab4e9d6
@ -20,7 +20,7 @@ describe('getWebpackConfig', () => {
|
|||||||
});
|
});
|
||||||
expect(config.module.rules).toContainEqual({
|
expect(config.module.rules).toContainEqual({
|
||||||
test: /\.(j|t)sx?$/,
|
test: /\.(j|t)sx?$/,
|
||||||
loader: 'ts-loader',
|
loader: require.resolve('ts-loader'),
|
||||||
exclude: [/node_modules/],
|
exclude: [/node_modules/],
|
||||||
options: {
|
options: {
|
||||||
configFile: './tsconfig.json',
|
configFile: './tsconfig.json',
|
||||||
|
|||||||
@ -37,7 +37,7 @@ export function getWebpackConfig(config: any) {
|
|||||||
rules: [
|
rules: [
|
||||||
{
|
{
|
||||||
test: /\.(j|t)sx?$/,
|
test: /\.(j|t)sx?$/,
|
||||||
loader: 'ts-loader',
|
loader: require.resolve('ts-loader'),
|
||||||
exclude: [/node_modules/],
|
exclude: [/node_modules/],
|
||||||
options: {
|
options: {
|
||||||
configFile: config.env.tsConfig,
|
configFile: config.env.tsConfig,
|
||||||
|
|||||||
@ -58,7 +58,7 @@ export function createWebpackConfig(
|
|||||||
use: [
|
use: [
|
||||||
'@svgr/webpack?-svgo,+titleProp,+ref![path]',
|
'@svgr/webpack?-svgo,+titleProp,+ref![path]',
|
||||||
{
|
{
|
||||||
loader: 'url-loader',
|
loader: require.resolve('url-loader'),
|
||||||
options: {
|
options: {
|
||||||
limit: 10000, // 10kB
|
limit: 10000, // 10kB
|
||||||
name: '[name].[hash:7].[ext]',
|
name: '[name].[hash:7].[ext]',
|
||||||
@ -70,7 +70,7 @@ export function createWebpackConfig(
|
|||||||
{
|
{
|
||||||
use: [
|
use: [
|
||||||
{
|
{
|
||||||
loader: 'url-loader',
|
loader: require.resolve('url-loader'),
|
||||||
options: {
|
options: {
|
||||||
limit: 10000, // 10kB
|
limit: 10000, // 10kB
|
||||||
name: '[name].[hash:7].[ext]',
|
name: '[name].[hash:7].[ext]',
|
||||||
|
|||||||
@ -47,7 +47,7 @@ describe('getBaseWebpackPartial', () => {
|
|||||||
);
|
);
|
||||||
expect(typescriptRule).toBeTruthy();
|
expect(typescriptRule).toBeTruthy();
|
||||||
|
|
||||||
expect(typescriptRule.loader).toEqual('ts-loader');
|
expect(typescriptRule.loader).toContain('ts-loader');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should split typescript type checking into a separate workers', () => {
|
it('should split typescript type checking into a separate workers', () => {
|
||||||
@ -131,7 +131,9 @@ describe('getBaseWebpackPartial', () => {
|
|||||||
const result = getBaseWebpackPartial(input);
|
const result = getBaseWebpackPartial(input);
|
||||||
|
|
||||||
expect(
|
expect(
|
||||||
result.module.rules.find((rule) => rule.loader === 'ts-loader').options
|
result.module.rules.find((rule) =>
|
||||||
|
rule.loader.toString().includes('ts-loader')
|
||||||
|
).options
|
||||||
).toEqual({
|
).toEqual({
|
||||||
configFile: 'tsconfig.json',
|
configFile: 'tsconfig.json',
|
||||||
transpileOnly: true,
|
transpileOnly: true,
|
||||||
|
|||||||
@ -36,7 +36,7 @@ export function getBaseWebpackPartial(
|
|||||||
rules: [
|
rules: [
|
||||||
{
|
{
|
||||||
test: /\.(j|t)sx?$/,
|
test: /\.(j|t)sx?$/,
|
||||||
loader: `ts-loader`,
|
loader: require.resolve(`ts-loader`),
|
||||||
exclude: /node_modules/,
|
exclude: /node_modules/,
|
||||||
options: {
|
options: {
|
||||||
configFile: options.tsConfig,
|
configFile: options.tsConfig,
|
||||||
|
|||||||
@ -5,7 +5,7 @@ function getWebpackConfig(config: Configuration) {
|
|||||||
config.module.rules.push(
|
config.module.rules.push(
|
||||||
{
|
{
|
||||||
test: /\.(png|jpe?g|gif|webp)$/,
|
test: /\.(png|jpe?g|gif|webp)$/,
|
||||||
loader: 'url-loader',
|
loader: require.resolve('url-loader'),
|
||||||
options: {
|
options: {
|
||||||
limit: 10000, // 10kB
|
limit: 10000, // 10kB
|
||||||
name: '[name].[hash:7].[ext]',
|
name: '[name].[hash:7].[ext]',
|
||||||
@ -22,7 +22,7 @@ function getWebpackConfig(config: Configuration) {
|
|||||||
use: [
|
use: [
|
||||||
'@svgr/webpack?-svgo,+titleProp,+ref![path]',
|
'@svgr/webpack?-svgo,+titleProp,+ref![path]',
|
||||||
{
|
{
|
||||||
loader: 'url-loader',
|
loader: require.resolve('url-loader'),
|
||||||
options: {
|
options: {
|
||||||
limit: 10000, // 10kB
|
limit: 10000, // 10kB
|
||||||
name: '[name].[hash:7].[ext]',
|
name: '[name].[hash:7].[ext]',
|
||||||
@ -34,7 +34,7 @@ function getWebpackConfig(config: Configuration) {
|
|||||||
{
|
{
|
||||||
use: [
|
use: [
|
||||||
{
|
{
|
||||||
loader: 'url-loader',
|
loader: require.resolve('url-loader'),
|
||||||
options: {
|
options: {
|
||||||
limit: 10000, // 10kB
|
limit: 10000, // 10kB
|
||||||
name: '[name].[hash:7].[ext]',
|
name: '[name].[hash:7].[ext]',
|
||||||
|
|||||||
@ -49,7 +49,7 @@ describe('getBaseWebpackPartial', () => {
|
|||||||
);
|
);
|
||||||
expect(rule).toBeTruthy();
|
expect(rule).toBeTruthy();
|
||||||
|
|
||||||
expect(rule.loader).toEqual('babel-loader');
|
expect(rule.loader).toContain('babel-loader');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should split typescript type checking into a separate workers', () => {
|
it('should split typescript type checking into a separate workers', () => {
|
||||||
@ -165,8 +165,9 @@ describe('getBaseWebpackPartial', () => {
|
|||||||
const result = getBaseWebpackPartial(input, true);
|
const result = getBaseWebpackPartial(input, true);
|
||||||
|
|
||||||
expect(
|
expect(
|
||||||
(result.module.rules.find((rule) => rule.loader === 'babel-loader')
|
(result.module.rules.find((rule) =>
|
||||||
.options as any).envName
|
rule.loader.toString().includes('babel-loader')
|
||||||
|
).options as any).envName
|
||||||
).toMatch('modern');
|
).toMatch('modern');
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -174,8 +175,9 @@ describe('getBaseWebpackPartial', () => {
|
|||||||
const result = getBaseWebpackPartial(input, false);
|
const result = getBaseWebpackPartial(input, false);
|
||||||
|
|
||||||
expect(
|
expect(
|
||||||
(result.module.rules.find((rule) => rule.loader === 'babel-loader')
|
(result.module.rules.find((rule) =>
|
||||||
.options as any).envName
|
rule.loader.toString().includes('babel-loader')
|
||||||
|
).options as any).envName
|
||||||
).toMatch('legacy');
|
).toMatch('legacy');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@ -48,7 +48,7 @@ export function getBaseWebpackPartial(
|
|||||||
rules: [
|
rules: [
|
||||||
{
|
{
|
||||||
test: /\.([jt])sx?$/,
|
test: /\.([jt])sx?$/,
|
||||||
loader: `babel-loader`,
|
loader: require.resolve(`babel-loader`),
|
||||||
exclude: /node_modules/,
|
exclude: /node_modules/,
|
||||||
options: {
|
options: {
|
||||||
rootMode: 'upward',
|
rootMode: 'upward',
|
||||||
|
|||||||
@ -316,7 +316,7 @@ export function getCommonConfig(wco: WebpackConfigOptions): Configuration {
|
|||||||
sourceMapUseRule = {
|
sourceMapUseRule = {
|
||||||
use: [
|
use: [
|
||||||
{
|
{
|
||||||
loader: 'source-map-loader',
|
loader: require.resolve('source-map-loader'),
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
@ -490,7 +490,7 @@ export function getCommonConfig(wco: WebpackConfigOptions): Configuration {
|
|||||||
rules: [
|
rules: [
|
||||||
{
|
{
|
||||||
test: /\.(eot|svg|cur|jpg|png|webp|gif|otf|ttf|woff|woff2|ani)$/,
|
test: /\.(eot|svg|cur|jpg|png|webp|gif|otf|ttf|woff|woff2|ani)$/,
|
||||||
loader: 'file-loader',
|
loader: require.resolve('file-loader'),
|
||||||
options: {
|
options: {
|
||||||
name: `[name]${hashFormat.file}.[ext]`,
|
name: `[name]${hashFormat.file}.[ext]`,
|
||||||
},
|
},
|
||||||
|
|||||||
@ -146,7 +146,7 @@ export function getStylesConfig(wco: WebpackConfigOptions) {
|
|||||||
test: /\.scss$|\.sass$/,
|
test: /\.scss$|\.sass$/,
|
||||||
use: [
|
use: [
|
||||||
{
|
{
|
||||||
loader: 'sass-loader',
|
loader: require.resolve('sass-loader'),
|
||||||
options: {
|
options: {
|
||||||
implementation: sassImplementation,
|
implementation: sassImplementation,
|
||||||
sourceMap: cssSourceMap,
|
sourceMap: cssSourceMap,
|
||||||
@ -164,7 +164,7 @@ export function getStylesConfig(wco: WebpackConfigOptions) {
|
|||||||
test: /\.less$/,
|
test: /\.less$/,
|
||||||
use: [
|
use: [
|
||||||
{
|
{
|
||||||
loader: 'less-loader',
|
loader: require.resolve('less-loader'),
|
||||||
options: {
|
options: {
|
||||||
sourceMap: cssSourceMap,
|
sourceMap: cssSourceMap,
|
||||||
javascriptEnabled: true,
|
javascriptEnabled: true,
|
||||||
@ -177,7 +177,7 @@ export function getStylesConfig(wco: WebpackConfigOptions) {
|
|||||||
test: /\.styl$/,
|
test: /\.styl$/,
|
||||||
use: [
|
use: [
|
||||||
{
|
{
|
||||||
loader: 'stylus-loader',
|
loader: require.resolve('stylus-loader'),
|
||||||
options: {
|
options: {
|
||||||
sourceMap: cssSourceMap,
|
sourceMap: cssSourceMap,
|
||||||
paths: includePaths,
|
paths: includePaths,
|
||||||
@ -192,9 +192,9 @@ export function getStylesConfig(wco: WebpackConfigOptions) {
|
|||||||
exclude: globalStylePaths,
|
exclude: globalStylePaths,
|
||||||
test,
|
test,
|
||||||
use: [
|
use: [
|
||||||
{ loader: 'raw-loader' },
|
{ loader: require.resolve('raw-loader') },
|
||||||
{
|
{
|
||||||
loader: 'postcss-loader',
|
loader: require.resolve('postcss-loader'),
|
||||||
options: {
|
options: {
|
||||||
ident: 'embedded',
|
ident: 'embedded',
|
||||||
plugins: postcssPluginCreator,
|
plugins: postcssPluginCreator,
|
||||||
@ -224,10 +224,10 @@ export function getStylesConfig(wco: WebpackConfigOptions) {
|
|||||||
use: [
|
use: [
|
||||||
buildOptions.extractCss
|
buildOptions.extractCss
|
||||||
? MiniCssExtractPlugin.loader
|
? MiniCssExtractPlugin.loader
|
||||||
: 'style-loader',
|
: require.resolve('style-loader'),
|
||||||
RawCssLoader,
|
RawCssLoader,
|
||||||
{
|
{
|
||||||
loader: 'postcss-loader',
|
loader: require.resolve('postcss-loader'),
|
||||||
options: {
|
options: {
|
||||||
ident: buildOptions.extractCss ? 'extracted' : 'embedded',
|
ident: buildOptions.extractCss ? 'extracted' : 'embedded',
|
||||||
plugins: postcssPluginCreator,
|
plugins: postcssPluginCreator,
|
||||||
|
|||||||
@ -121,7 +121,7 @@ function getStylesPartial(
|
|||||||
loaderConfig.loader === 'raw-loader'
|
loaderConfig.loader === 'raw-loader'
|
||||||
) {
|
) {
|
||||||
return {
|
return {
|
||||||
loader: 'style-loader',
|
loader: require.resolve('style-loader'),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
return loaderConfig;
|
return loaderConfig;
|
||||||
@ -138,10 +138,10 @@ function getStylesPartial(
|
|||||||
{
|
{
|
||||||
loader: options.extractCss
|
loader: options.extractCss
|
||||||
? MiniCssExtractPlugin.loader
|
? MiniCssExtractPlugin.loader
|
||||||
: 'style-loader',
|
: require.resolve('style-loader'),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
loader: 'css-loader',
|
loader: require.resolve('css-loader'),
|
||||||
options: {
|
options: {
|
||||||
modules: true,
|
modules: true,
|
||||||
importLoaders: 1,
|
importLoaders: 1,
|
||||||
@ -155,16 +155,16 @@ function getStylesPartial(
|
|||||||
{
|
{
|
||||||
loader: options.extractCss
|
loader: options.extractCss
|
||||||
? MiniCssExtractPlugin.loader
|
? MiniCssExtractPlugin.loader
|
||||||
: 'style-loader',
|
: require.resolve('style-loader'),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
loader: 'css-loader',
|
loader: require.resolve('css-loader'),
|
||||||
options: {
|
options: {
|
||||||
modules: true,
|
modules: true,
|
||||||
importLoaders: 1,
|
importLoaders: 1,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{ loader: 'sass-loader' },
|
{ loader: require.resolve('sass-loader') },
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
...rules,
|
...rules,
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user