From a8930e40830f72526bb0191b308a850b379d277d Mon Sep 17 00:00:00 2001 From: Joe Haddad Date: Thu, 10 Sep 2020 11:12:57 -0400 Subject: [PATCH] Allow components to import Global CSS from npm --- .../build/webpack/config/blocks/css/index.ts | 77 +++++++++++++------ 1 file changed, 54 insertions(+), 23 deletions(-) diff --git a/packages/next/build/webpack/config/blocks/css/index.ts b/packages/next/build/webpack/config/blocks/css/index.ts index 5843509d6c431..ff32c0a553a93 100644 --- a/packages/next/build/webpack/config/blocks/css/index.ts +++ b/packages/next/build/webpack/config/blocks/css/index.ts @@ -154,7 +154,7 @@ export const css = curry(async function css( loader({ oneOf: [ { - test: [regexCssModules, regexSassModules].filter(Boolean), + test: [regexCssModules, regexSassModules], use: { loader: 'error-loader', options: { @@ -171,13 +171,13 @@ export const css = curry(async function css( loader({ oneOf: [ { - test: [regexCssGlobal, regexSassGlobal].filter(Boolean), + test: [regexCssGlobal, regexSassGlobal], use: require.resolve('next/dist/compiled/ignore-loader'), }, ], }) ) - } else if (ctx.customAppFile) { + } else { fns.push( loader({ oneOf: [ @@ -188,28 +188,59 @@ export const css = curry(async function css( // See https://github.com/webpack/webpack/issues/6571 sideEffects: true, test: regexCssGlobal, - issuer: { and: [ctx.customAppFile] }, + // We only allow Global CSS to be imported anywhere in the + // application if it comes from node_modules. This is a best-effort + // heuristic that makes a safety trade-off for better + // interoperability with npm packages that require CSS. Without + // this ability, the component's CSS would have to be included for + // the entire app instead of specific page where it's required. + include: { and: [/node_modules/] }, + // Global CSS is only supported in the user's application, not in + // node_modules. + issuer: { + and: [ctx.rootDirectory], + not: [/node_modules/], + }, use: getGlobalCssLoader(ctx, postCssPlugins), }, ], }) ) - fns.push( - loader({ - oneOf: [ - { - // A global Sass import always has side effects. Webpack will tree - // shake the Sass without this option if the issuer claims to have - // no side-effects. - // See https://github.com/webpack/webpack/issues/6571 - sideEffects: true, - test: regexSassGlobal, - issuer: { and: [ctx.customAppFile] }, - use: getGlobalCssLoader(ctx, postCssPlugins, sassPreprocessors), - }, - ], - }) - ) + + if (ctx.customAppFile) { + fns.push( + loader({ + oneOf: [ + { + // A global CSS import always has side effects. Webpack will tree + // shake the CSS without this option if the issuer claims to have + // no side-effects. + // See https://github.com/webpack/webpack/issues/6571 + sideEffects: true, + test: regexCssGlobal, + issuer: { and: [ctx.customAppFile] }, + use: getGlobalCssLoader(ctx, postCssPlugins), + }, + ], + }) + ) + fns.push( + loader({ + oneOf: [ + { + // A global Sass import always has side effects. Webpack will tree + // shake the Sass without this option if the issuer claims to have + // no side-effects. + // See https://github.com/webpack/webpack/issues/6571 + sideEffects: true, + test: regexSassGlobal, + issuer: { and: [ctx.customAppFile] }, + use: getGlobalCssLoader(ctx, postCssPlugins, sassPreprocessors), + }, + ], + }) + ) + } } // Throw an error for Global CSS used inside of `node_modules` @@ -217,7 +248,7 @@ export const css = curry(async function css( loader({ oneOf: [ { - test: [regexCssGlobal, regexSassGlobal].filter(Boolean), + test: [regexCssGlobal, regexSassGlobal], issuer: { and: [/node_modules/] }, use: { loader: 'error-loader', @@ -235,7 +266,7 @@ export const css = curry(async function css( loader({ oneOf: [ { - test: [regexCssGlobal, regexSassGlobal].filter(Boolean), + test: [regexCssGlobal, regexSassGlobal], use: { loader: 'error-loader', options: { @@ -294,7 +325,7 @@ export const css = curry(async function css( // selector), this assumption is required to code-split CSS. // // If this warning were to trigger, it'd be unactionable by the user, - // but also not valid -- so we disable it. + // but likely not valid -- so we disable it. ignoreOrder: true, }) )