fix(nextjs): add Next.js config enhancer for supporting css moduels in workspace libs (#4047)
This commit is contained in:
parent
1f66f4cc42
commit
a297db6324
@ -7,7 +7,6 @@ import {
|
|||||||
readJson,
|
readJson,
|
||||||
runCLI,
|
runCLI,
|
||||||
runCLIAsync,
|
runCLIAsync,
|
||||||
supportUi,
|
|
||||||
uniq,
|
uniq,
|
||||||
updateFile,
|
updateFile,
|
||||||
} from '@nrwl/e2e/utils';
|
} from '@nrwl/e2e/utils';
|
||||||
@ -87,6 +86,24 @@ forEachCli('nx', () => {
|
|||||||
const mainPath = `apps/${appName}/pages/index.tsx`;
|
const mainPath = `apps/${appName}/pages/index.tsx`;
|
||||||
updateFile(mainPath, `import '@proj/${libName}';\n` + readFile(mainPath));
|
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 <div className={styles.container}>Hello</div>;
|
||||||
|
}
|
||||||
|
`
|
||||||
|
);
|
||||||
|
updateFile(
|
||||||
|
`libs/${libName}/src/lib/style.module.css`,
|
||||||
|
`
|
||||||
|
.container {}
|
||||||
|
`
|
||||||
|
);
|
||||||
|
|
||||||
await checkApp(appName, {
|
await checkApp(appName, {
|
||||||
checkUnitTest: true,
|
checkUnitTest: true,
|
||||||
checkLint: true,
|
checkLint: true,
|
||||||
|
|||||||
91
packages/next/plugins/with-nx.ts
Normal file
91
packages/next/plugins/with-nx.ts
Normal file
@ -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;
|
||||||
@ -1,25 +1,27 @@
|
|||||||
|
const withNx = require('@nrwl/next/plugins/with-nx');
|
||||||
|
|
||||||
<% if (style === 'less') { %>
|
<% if (style === 'less') { %>
|
||||||
const withLess = require('@zeit/next-less');
|
const withLess = require('@zeit/next-less');
|
||||||
module.exports = withLess({
|
module.exports = withLess(withNx({
|
||||||
// Set this to true if you use CSS modules.
|
// Set this to true if you use CSS modules.
|
||||||
// See: https://github.com/css-modules/css-modules
|
// See: https://github.com/css-modules/css-modules
|
||||||
cssModules: false
|
cssModules: false
|
||||||
});
|
}));
|
||||||
<% } else if (style === 'styl') { %>
|
<% } else if (style === 'styl') { %>
|
||||||
const withStylus = require('@zeit/next-stylus');
|
const withStylus = require('@zeit/next-stylus');
|
||||||
module.exports = withStylus({
|
module.exports = withStylus(withNx({
|
||||||
// Set this to true if you use CSS modules.
|
// Set this to true if you use CSS modules.
|
||||||
// See: https://github.com/css-modules/css-modules
|
// See: https://github.com/css-modules/css-modules
|
||||||
cssModules: false
|
cssModules: false
|
||||||
});
|
}));
|
||||||
<% } else if (
|
<% } else if (
|
||||||
style === 'styled-components'
|
style === 'styled-components'
|
||||||
||style === '@emotion/styled'
|
||style === '@emotion/styled'
|
||||||
|| style === 'styled-jsx'
|
|| style === 'styled-jsx'
|
||||||
|| style === 'none'
|
|| style === 'none'
|
||||||
) { %>
|
) { %>
|
||||||
module.exports ={};
|
module.exports = withNx({});
|
||||||
<% } else {
|
<% } else {
|
||||||
// Defaults to CSS/SASS (which don't need plugin as of Next 9.3) %>
|
// Defaults to CSS/SASS (which don't need plugin as of Next 9.3) %>
|
||||||
module.exports ={};
|
module.exports = withNx({});
|
||||||
<% } %>
|
<% } %>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user