@nx/next
Version:
139 lines (138 loc) • 6.94 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.libraryGenerator = libraryGenerator;
exports.libraryGeneratorInternal = libraryGeneratorInternal;
const devkit_1 = require("@nx/devkit");
const library_1 = require("@nx/react/src/generators/library/library");
const js_1 = require("@nx/js");
const versions_1 = require("@nx/react/src/utils/versions");
const init_1 = require("../init/init");
const normalize_options_1 = require("./lib/normalize-options");
const update_vite_config_1 = require("./lib/update-vite-config");
const versions_2 = require("../../utils/versions");
const ts_solution_setup_1 = require("@nx/js/src/utils/typescript/ts-solution-setup");
const sort_fields_1 = require("@nx/js/src/utils/package-json/sort-fields");
async function libraryGenerator(host, rawOptions) {
return await libraryGeneratorInternal(host, {
addPlugin: false,
useProjectJson: true,
...rawOptions,
});
}
async function libraryGeneratorInternal(host, rawOptions) {
const tasks = [];
const addTsPlugin = (0, ts_solution_setup_1.shouldConfigureTsSolutionSetup)(host, rawOptions.addPlugin);
const jsInitTask = await (0, js_1.initGenerator)(host, {
js: rawOptions.js,
addTsPlugin,
skipPackageJson: rawOptions.skipPackageJson,
skipFormat: true,
});
tasks.push(jsInitTask);
const options = await (0, normalize_options_1.normalizeOptions)(host, rawOptions);
const initTask = await (0, init_1.nextInitGenerator)(host, {
...options,
skipFormat: true,
});
tasks.push(initTask);
const libTask = await (0, library_1.libraryGenerator)(host, {
...options,
skipFormat: true,
});
tasks.push(libTask);
if (!options.skipPackageJson) {
const devDependencies = {};
if (options.linter === 'eslint') {
devDependencies['eslint-config-next'] = versions_2.eslintConfigNextVersion;
devDependencies['@next/eslint-plugin-next'] = versions_2.eslintConfigNextVersion;
}
if (options.unitTestRunner && options.unitTestRunner !== 'none') {
devDependencies['@testing-library/react'] = versions_1.testingLibraryReactVersion;
devDependencies['@testing-library/dom'] = versions_1.testingLibraryDomVersion;
}
tasks.push((0, devkit_1.addDependenciesToPackageJson)(host, { tslib: versions_2.tsLibVersion }, devDependencies));
}
const indexPath = (0, devkit_1.joinPathFragments)(options.projectRoot, 'src', `index.${options.js ? 'js' : 'ts'}`);
const indexContent = host.read(indexPath, 'utf-8');
host.write(indexPath, `// Use this file to export React client components (e.g. those with 'use client' directive) or other non-server utilities\n${indexContent}`);
// Additional entry for Next.js libraries so React Server Components are exported from a separate entry point.
// This is needed because RSC exported from `src/index.ts` will mark the entire file as server-only and throw an error when used from a client component.
// See: https://github.com/nrwl/nx/issues/15830
const serverEntryPath = (0, devkit_1.joinPathFragments)(options.projectRoot, './src', 'server.' + (options.js ? 'js' : 'ts'));
host.write((0, devkit_1.joinPathFragments)(options.projectRoot, 'src', `server.${options.js ? 'js' : 'ts'}`), `// Use this file to export React server components
export * from './lib/hello-server';`);
host.write((0, devkit_1.joinPathFragments)(options.projectRoot, 'src/lib', `hello-server.${options.js ? 'js' : 'tsx'}`), `// React server components are async so you make database or API calls.
export async function HelloServer() {
return <h1>Hello Server</h1>;
}
`);
const isTsSolutionSetup = (0, ts_solution_setup_1.isUsingTsSolutionSetup)(host);
if (!options.skipTsConfig && !isTsSolutionSetup) {
(0, js_1.addTsConfigPath)(host, `${options.importPath}/server`, [serverEntryPath]);
}
// Configure Vite and package.json for server entry point when using Vite bundler
if (options.bundler === 'vite') {
// Update vite.config.mts to support multiple entry points
const viteConfigPath = (0, devkit_1.joinPathFragments)(options.projectRoot, 'vite.config.mts');
(0, update_vite_config_1.updateViteConfigForServerEntry)(host, viteConfigPath);
// Update package.json to include server export
const packageJsonPath = (0, devkit_1.joinPathFragments)(options.projectRoot, 'package.json');
if (host.exists(packageJsonPath)) {
(0, devkit_1.updateJson)(host, packageJsonPath, (json) => {
if (!json.exports) {
json.exports = {};
}
// Add server export
const serverExport = {};
// For TS Solution setups, include development condition
if (isTsSolutionSetup) {
const customConditionName = (0, ts_solution_setup_1.getDefinedCustomConditionName)(host);
serverExport[customConditionName] = './src/server.ts';
}
serverExport.types = './dist/server.d.ts';
serverExport.import = './dist/server.js';
serverExport.default = './dist/server.js';
json.exports['./server'] = serverExport;
return json;
});
}
}
(0, devkit_1.updateJson)(host, (0, devkit_1.joinPathFragments)(options.projectRoot, 'tsconfig.json'), (json) => {
if (options.style === '@emotion/styled') {
json.compilerOptions.jsxImportSource = '@emotion/react';
}
return json;
});
(0, devkit_1.updateJson)(host, (0, devkit_1.joinPathFragments)(options.projectRoot, 'tsconfig.lib.json'), (json) => {
if (!json.compilerOptions) {
json.compilerOptions = {
types: [],
};
}
if (!json.compilerOptions.types) {
json.compilerOptions.types = [];
}
json.compilerOptions.types = [
...json.compilerOptions.types,
'next',
'@nx/next/typings/image.d.ts',
];
return json;
});
(0, ts_solution_setup_1.updateTsconfigFiles)(host, options.projectRoot, 'tsconfig.lib.json', {
jsx: 'react-jsx',
module: 'esnext',
moduleResolution: 'bundler',
}, options.linter === 'eslint'
? ['eslint.config.js', 'eslint.config.cjs', 'eslint.config.mjs']
: undefined);
if (options.isUsingTsSolutionConfig) {
await (0, ts_solution_setup_1.addProjectToTsSolutionWorkspace)(host, options.projectRoot);
}
(0, sort_fields_1.sortPackageJsonFields)(host, options.projectRoot);
if (!options.skipFormat) {
await (0, devkit_1.formatFiles)(host);
}
return (0, devkit_1.runTasksInSerial)(...tasks);
}
exports.default = libraryGenerator;