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,
|
||||
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 <div className={styles.container}>Hello</div>;
|
||||
}
|
||||
`
|
||||
);
|
||||
updateFile(
|
||||
`libs/${libName}/src/lib/style.module.css`,
|
||||
`
|
||||
.container {}
|
||||
`
|
||||
);
|
||||
|
||||
await checkApp(appName, {
|
||||
checkUnitTest: 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') { %>
|
||||
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({});
|
||||
<% } %>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user