-
Notifications
You must be signed in to change notification settings - Fork 2.9k
Expand file tree
/
Copy pathpage.ts
More file actions
101 lines (89 loc) · 3.02 KB
/
Copy pathpage.ts
File metadata and controls
101 lines (89 loc) · 3.02 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
import {
determineArtifactNameAndDirectoryOptions,
getRelativeCwd,
} from '@nx/devkit/internal';
import { componentGenerator as reactComponentGenerator } from '@nx/react';
import {
formatFiles,
joinPathFragments,
readProjectConfiguration,
runTasksInSerial,
Tree,
} from '@nx/devkit';
import { addStyleDependencies } from '../../utils/styles';
import { Schema } from './schema';
/*
* This schematic is basically the React component one, but for Next we need
* extra dependencies for css, sass, less style options, and make sure
* it is under `pages` folder.
*/
export async function pageGenerator(host: Tree, schema: Schema) {
const options = await normalizeOptions(host, schema);
const componentTask = await reactComponentGenerator(host, {
...options,
isNextPage: true,
export: false,
classComponent: false,
routing: false,
skipTests: !options.withTests,
skipFormat: true,
});
const project = readProjectConfiguration(host, options.projectName);
const styledTask = addStyleDependencies(host, {
style: options.style,
swc: !host.exists(joinPathFragments(project.root, '.babelrc')),
});
if (!options.skipFormat) {
await formatFiles(host);
}
return runTasksInSerial(componentTask, styledTask);
}
async function normalizeOptions(host: Tree, options: Schema) {
// Get the project name first so we can determine the router directory
const { project: determinedProjectName } =
await determineArtifactNameAndDirectoryOptions(host, {
name: options.name,
path: options.path,
});
const project = readProjectConfiguration(host, determinedProjectName);
// app/ is a reserved folder in nextjs so it is safe to check it's existence
const isAppRouter =
host.exists(`${project.root}/app`) ||
host.exists(`${project.root}/src/app`);
let pageSymbolName = options.name;
if (!pageSymbolName) {
// if `name` is not provided, we use the last segment of the path
if (options.path !== '.' && options.path !== '') {
pageSymbolName = options.path.split('/').pop();
} else {
// the user must have cd into a previously created directory, we need to
// resolve the cwd to get it
const cwd = getRelativeCwd();
if (cwd !== '.' && cwd !== '') {
pageSymbolName = cwd.split('/').pop();
} else {
// this can only happen when running from the workspace root, in which
// case, we don't have a good way to automatically determine the name
throw new Error(
'Cannot determine the page name, please provide a `name` or `path` option.'
);
}
}
}
const fileName = options.fileName || (isAppRouter ? 'page' : 'index');
const { js, ...rest } = options;
const { project: projectName, filePath } =
await determineArtifactNameAndDirectoryOptions(host, {
name: pageSymbolName,
path: joinPathFragments(
options.path,
`${fileName}.${js ? 'jsx' : 'tsx'}`
),
});
return {
...rest,
path: filePath,
projectName,
};
}
export default pageGenerator;