diff --git a/e2e/next/src/next.test.ts b/e2e/next/src/next.test.ts
index 4f50144b78..c58e929055 100644
--- a/e2e/next/src/next.test.ts
+++ b/e2e/next/src/next.test.ts
@@ -7,7 +7,6 @@ import {
readJson,
runCLI,
runCLIAsync,
- supportUi,
uniq,
updateFile,
} from '@nrwl/e2e/utils';
@@ -87,6 +86,24 @@ forEachCli('nx', () => {
const mainPath = `apps/${appName}/pages/index.tsx`;
updateFile(mainPath, `import '@proj/${libName}';\n` + readFile(mainPath));
+ // Update lib to use css modules
+ updateFile(
+ `libs/${libName}/src/lib/${libName}.tsx`,
+ `
+ import React from 'react';
+ import styles from './style.module.css';
+ export function Test() {
+ return
Hello
;
+ }
+ `
+ );
+ updateFile(
+ `libs/${libName}/src/lib/style.module.css`,
+ `
+ .container {}
+ `
+ );
+
await checkApp(appName, {
checkUnitTest: true,
checkLint: true,
diff --git a/packages/next/plugins/with-nx.ts b/packages/next/plugins/with-nx.ts
new file mode 100644
index 0000000000..a0758a3d5a
--- /dev/null
+++ b/packages/next/plugins/with-nx.ts
@@ -0,0 +1,91 @@
+const { join } = require('path');
+const { appRootPath } = require('@nrwl/workspace/src/utils/app-root');
+const { workspaceLayout } = require('@nrwl/workspace/src/core/file-utils');
+
+function regexEqual(x, y) {
+ return (
+ x instanceof RegExp &&
+ y instanceof RegExp &&
+ x.source === y.source &&
+ x.global === y.global &&
+ x.ignoreCase === y.ignoreCase &&
+ x.multiline === y.multiline
+ );
+}
+
+function withNx(nextConfig = {} as any) {
+ const userWebpack = nextConfig.webpack || ((x) => x);
+ return {
+ ...nextConfig,
+ /*
+ * Modify the Next.js webpack config to allow workspace libs to use css modules.
+ *
+ * Note: This would be easier if Next.js exposes css-loader and sass-loader on `defaultLoaders`.
+ */
+ webpack: (config, { defaultLoaders }) => {
+ // Include workspace libs in css/sass loaders
+ const includes = [join(appRootPath, workspaceLayout().libsDir)];
+
+ const nextCssLoaders = config.module.rules.find(
+ (rule) => typeof rule.oneOf === 'object'
+ );
+
+ // webpack config is not as expected
+ if (!nextCssLoaders) return config;
+
+ /*
+ * 1. Modify css loader to enable module support for workspace libs
+ */
+ const nextCssLoader = nextCssLoaders.oneOf.find(
+ (rule) =>
+ rule.sideEffects === false && regexEqual(rule.test, /\.module\.css$/)
+ );
+ // Might not be found if Next.js webpack config changes in the future
+ if (nextCssLoader) {
+ nextCssLoader.issuer.or = nextCssLoader.issuer.and
+ ? nextCssLoader.issuer.and.concat(includes)
+ : includes;
+ delete nextCssLoader.issuer.and;
+ }
+
+ /*
+ * 2. Modify sass loader to enable module support for workspace libs
+ */
+ const nextSassLoader = nextCssLoaders.oneOf.find(
+ (rule) =>
+ rule.sideEffects === false &&
+ regexEqual(rule.test, /\.module\.(scss|sass)$/)
+ );
+ // Might not be found if Next.js webpack config changes in the future
+ if (nextSassLoader) {
+ nextSassLoader.issuer.or = nextSassLoader.issuer.and
+ ? nextSassLoader.issuer.and.concat(includes)
+ : includes;
+ delete nextSassLoader.issuer.and;
+ }
+
+ /*
+ * 3. Modify error loader to ignore css modules used by workspace libs
+ */
+ const nextErrorCssModuleLoader = nextCssLoaders.oneOf.find(
+ (rule) =>
+ rule.use &&
+ rule.use.loader === 'error-loader' &&
+ rule.use.options &&
+ (rule.use.options.reason ===
+ 'CSS Modules \u001b[1mcannot\u001b[22m be imported from within \u001b[1mnode_modules\u001b[22m.\n' +
+ 'Read more: https://err.sh/next.js/css-modules-npm' ||
+ rule.use.options.reason ===
+ 'CSS Modules cannot be imported from within node_modules.\nRead more: https://err.sh/next.js/css-modules-npm')
+ );
+ // Might not be found if Next.js webpack config changes in the future
+ if (nextErrorCssModuleLoader) {
+ nextErrorCssModuleLoader.exclude = includes;
+ }
+
+ return userWebpack(config);
+ },
+ };
+}
+
+module.exports = withNx;
diff --git a/packages/next/src/schematics/application/files/next.config.js__tmpl__ b/packages/next/src/schematics/application/files/next.config.js__tmpl__
index fb13bf5b36..4fa42b1c9d 100644
--- a/packages/next/src/schematics/application/files/next.config.js__tmpl__
+++ b/packages/next/src/schematics/application/files/next.config.js__tmpl__
@@ -1,25 +1,27 @@
+const withNx = require('@nrwl/next/plugins/with-nx');
+
<% if (style === 'less') { %>
const withLess = require('@zeit/next-less');
-module.exports = withLess({
+module.exports = withLess(withNx({
// Set this to true if you use CSS modules.
// See: https://github.com/css-modules/css-modules
cssModules: false
-});
+}));
<% } else if (style === 'styl') { %>
const withStylus = require('@zeit/next-stylus');
-module.exports = withStylus({
+module.exports = withStylus(withNx({
// Set this to true if you use CSS modules.
// See: https://github.com/css-modules/css-modules
cssModules: false
-});
+}));
<% } else if (
style === 'styled-components'
||style === '@emotion/styled'
|| style === 'styled-jsx'
|| style === 'none'
) { %>
-module.exports ={};
+module.exports = withNx({});
<% } else {
// Defaults to CSS/SASS (which don't need plugin as of Next 9.3) %>
-module.exports ={};
+module.exports = withNx({});
<% } %>