@graphcommerce/next-config 3.1.6 → 4.30.0-canary.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +5 -25
- package/dist/index.js +23 -117
- package/dist/utils/isMonorepo.d.ts +1 -0
- package/dist/utils/isMonorepo.js +14 -0
- package/dist/utils/resolveDependenciesSync.d.ts +10 -0
- package/dist/utils/resolveDependenciesSync.js +57 -0
- package/dist/withGraphCommerce.d.ts +6 -0
- package/dist/withGraphCommerce.js +55 -0
- package/package.json +2 -1
- package/src/index.ts +8 -158
- package/src/utils/isMonorepo.ts +8 -0
- package/src/utils/resolveDependenciesSync.ts +59 -0
- package/src/withGraphCommerce.ts +65 -0
package/dist/index.d.ts
CHANGED
|
@@ -1,26 +1,6 @@
|
|
|
1
1
|
import { NextConfig } from 'next/dist/server/config-shared';
|
|
2
|
-
export
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
};
|
|
8
|
-
};
|
|
9
|
-
declare type TreeNode = {
|
|
10
|
-
name: string;
|
|
11
|
-
children?: TreeNode[];
|
|
12
|
-
hint: null;
|
|
13
|
-
depth: number;
|
|
14
|
-
color?: string;
|
|
15
|
-
shadow?: boolean;
|
|
16
|
-
};
|
|
17
|
-
export declare type ListInfo = {
|
|
18
|
-
type: 'tree';
|
|
19
|
-
data: {
|
|
20
|
-
type: 'list';
|
|
21
|
-
trees: TreeNode[];
|
|
22
|
-
};
|
|
23
|
-
};
|
|
24
|
-
export declare function withYarn1Scopes(scopes?: string[]): (config: NextConfig) => NextConfig;
|
|
25
|
-
export declare function withYarn1Workspaces(modules?: string[]): (config: NextConfig) => NextConfig;
|
|
26
|
-
export {};
|
|
2
|
+
export * from './utils/isMonorepo';
|
|
3
|
+
export * from './utils/resolveDependenciesSync';
|
|
4
|
+
export * from './withGraphCommerce';
|
|
5
|
+
export declare function withYarn1Workspaces(packages?: string[]): (config: NextConfig) => NextConfig;
|
|
6
|
+
export declare function withYarn1Scopes(packages?: string[]): (config: NextConfig) => NextConfig;
|
package/dist/index.js
CHANGED
|
@@ -1,123 +1,29 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var
|
|
3
|
-
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
4
15
|
};
|
|
5
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.
|
|
7
|
-
const
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
return {
|
|
14
|
-
...nextConfig,
|
|
15
|
-
webpack: (config, options) => {
|
|
16
|
-
// Allow importing yml/yaml files for graphql-mesh
|
|
17
|
-
config.module?.rules?.push({ test: /\.ya?ml$/, use: 'js-yaml-loader' });
|
|
18
|
-
// To properly properly treeshake @apollo/client we need to define the __DEV__ property
|
|
19
|
-
if (!options.isServer) {
|
|
20
|
-
config.plugins = [new webpack_1.DefinePlugin({ __DEV__: options.dev }), ...(config.plugins ?? [])];
|
|
21
|
-
}
|
|
22
|
-
// @lingui .po file support
|
|
23
|
-
config.module?.rules?.push({ test: /\.po/, use: '@lingui/loader' });
|
|
24
|
-
config.experiments = {
|
|
25
|
-
layers: true,
|
|
26
|
-
topLevelAwait: true,
|
|
27
|
-
};
|
|
28
|
-
config.snapshot = {
|
|
29
|
-
...(config.snapshot ?? {}),
|
|
30
|
-
managedPaths: [/^(.+?[\\/]node_modules[\\/])(?!@graphcommerce)/],
|
|
31
|
-
};
|
|
32
|
-
// `config.watchOptions.ignored = ['**/.git/**', '**/node_modules/**', '**/.next/**']
|
|
33
|
-
// Replace the '**/node_modules/**' with a regex that excludes node_modules except @graphcommerce
|
|
34
|
-
config.watchOptions = {
|
|
35
|
-
...(config.watchOptions ?? {}),
|
|
36
|
-
ignored: ['**/.git/**', '**/node_modules/!(@graphcommerce)**', '**/.next/**'],
|
|
37
|
-
};
|
|
38
|
-
if (!config.resolve)
|
|
39
|
-
config.resolve = {};
|
|
40
|
-
config.resolve.alias = {
|
|
41
|
-
...config.resolve.alias,
|
|
42
|
-
'@mui/base': '@mui/base/modern',
|
|
43
|
-
'@mui/lab': '@mui/lab/modern',
|
|
44
|
-
'@mui/material': '@mui/material/modern',
|
|
45
|
-
'@mui/styled-engine': '@mui/styled-engine/modern',
|
|
46
|
-
'@mui/system': '@mui/system/modern',
|
|
47
|
-
};
|
|
48
|
-
return typeof nextConfig.webpack === 'function' ? nextConfig.webpack(config, options) : config;
|
|
49
|
-
},
|
|
50
|
-
};
|
|
17
|
+
exports.withYarn1Scopes = exports.withYarn1Workspaces = void 0;
|
|
18
|
+
const withGraphCommerce_1 = require("./withGraphCommerce");
|
|
19
|
+
__exportStar(require("./utils/isMonorepo"), exports);
|
|
20
|
+
__exportStar(require("./utils/resolveDependenciesSync"), exports);
|
|
21
|
+
__exportStar(require("./withGraphCommerce"), exports);
|
|
22
|
+
function withYarn1Workspaces(packages = []) {
|
|
23
|
+
return (0, withGraphCommerce_1.withGraphCommerce)({ packages });
|
|
51
24
|
}
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
const cacheKey = `.next/cache/withYarn1Scopes.${hashSum}.json`;
|
|
56
|
-
let modules;
|
|
57
|
-
try {
|
|
58
|
-
modules = JSON.parse((0, fs_1.readFileSync)(cacheKey, 'utf-8'));
|
|
59
|
-
}
|
|
60
|
-
catch (e) {
|
|
61
|
-
const infoJson = (0, child_process_1.execSync)('yarn list --json', { encoding: 'utf-8' });
|
|
62
|
-
const workspaceInfo = JSON.parse(infoJson);
|
|
63
|
-
const list = new Set();
|
|
64
|
-
const walk = (node) => {
|
|
65
|
-
let packageName;
|
|
66
|
-
if (node.name.includes('/')) {
|
|
67
|
-
const [scope, nameWithVersion] = node.name.split('/');
|
|
68
|
-
const [name] = nameWithVersion.split('@');
|
|
69
|
-
packageName = `${scope}/${name}`;
|
|
70
|
-
}
|
|
71
|
-
else {
|
|
72
|
-
const [name] = node.name.split('@');
|
|
73
|
-
packageName = `${name}`;
|
|
74
|
-
}
|
|
75
|
-
const found = scopes.find((scope) => packageName.startsWith(scope));
|
|
76
|
-
if (found)
|
|
77
|
-
list.add(packageName);
|
|
78
|
-
node.children?.forEach(walk);
|
|
79
|
-
};
|
|
80
|
-
workspaceInfo.data.trees.map(walk);
|
|
81
|
-
modules = [...list.values()];
|
|
82
|
-
(0, fs_1.mkdirSync)('.next/cache/', { recursive: true });
|
|
83
|
-
(0, fs_1.writeFileSync)(cacheKey, JSON.stringify(modules));
|
|
84
|
-
}
|
|
85
|
-
return (config) => extendConfig((0, next_transpile_modules_1.default)(modules)(config));
|
|
25
|
+
exports.withYarn1Workspaces = withYarn1Workspaces;
|
|
26
|
+
function withYarn1Scopes(packages) {
|
|
27
|
+
return (0, withGraphCommerce_1.withGraphCommerce)({ packages });
|
|
86
28
|
}
|
|
87
29
|
exports.withYarn1Scopes = withYarn1Scopes;
|
|
88
|
-
function withYarn1Workspaces(modules = []) {
|
|
89
|
-
const packageStr = (0, fs_1.readFileSync)('package.json', 'utf-8');
|
|
90
|
-
const packageJson = JSON.parse(packageStr);
|
|
91
|
-
const hashSum = (0, crypto_1.createHash)('sha256').update(packageStr, 'utf-8').digest('hex').slice(0, 10);
|
|
92
|
-
let infoJson;
|
|
93
|
-
const cacheKey = `.next/cache/withYarn1Workspaces.${hashSum}.json`;
|
|
94
|
-
try {
|
|
95
|
-
infoJson = (0, fs_1.readFileSync)(cacheKey, 'utf-8');
|
|
96
|
-
}
|
|
97
|
-
catch (e) {
|
|
98
|
-
infoJson = (0, child_process_1.execSync)('yarn list info --json', { encoding: 'utf-8' });
|
|
99
|
-
try {
|
|
100
|
-
(0, fs_1.mkdirSync)('.next/cache/', { recursive: true });
|
|
101
|
-
(0, fs_1.writeFileSync)(cacheKey, infoJson);
|
|
102
|
-
}
|
|
103
|
-
catch (er) {
|
|
104
|
-
// do nothing
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
|
108
|
-
const workspaceInfo = JSON.parse(JSON.parse(infoJson).data);
|
|
109
|
-
const requestedPackages = [
|
|
110
|
-
...Object.keys(packageJson.dependencies ?? {}),
|
|
111
|
-
...Object.keys(packageJson.devDependencies ?? {}),
|
|
112
|
-
];
|
|
113
|
-
const entries = Object.entries(workspaceInfo);
|
|
114
|
-
const m = new Set(modules);
|
|
115
|
-
entries.forEach(([p, b]) => {
|
|
116
|
-
if (requestedPackages.includes(p)) {
|
|
117
|
-
m.add(p);
|
|
118
|
-
b.workspaceDependencies.forEach((wp) => m.add(wp));
|
|
119
|
-
}
|
|
120
|
-
});
|
|
121
|
-
return (config) => extendConfig((0, next_transpile_modules_1.default)([...m.values()])(config));
|
|
122
|
-
}
|
|
123
|
-
exports.withYarn1Workspaces = withYarn1Workspaces;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function isMonorepo(): boolean;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.isMonorepo = void 0;
|
|
7
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
8
|
+
function isMonorepo() {
|
|
9
|
+
const root = process.cwd();
|
|
10
|
+
const meshDir = node_path_1.default.dirname(require.resolve('@graphcommerce/graphql-mesh'));
|
|
11
|
+
const relativePath = node_path_1.default.join(node_path_1.default.relative(meshDir, root), '/');
|
|
12
|
+
return relativePath.startsWith(`..${node_path_1.default.sep}..${node_path_1.default.sep}examples`);
|
|
13
|
+
}
|
|
14
|
+
exports.isMonorepo = isMonorepo;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This will return a list of all dependencies that have `graphcommerce` in the name, matching:
|
|
3
|
+
*
|
|
4
|
+
* - `@graphcommerce/package-name`
|
|
5
|
+
* - `@mycompany/graphcommerce-my-feature`
|
|
6
|
+
*
|
|
7
|
+
* It will traverse children until it finds a package that doesn't contain graphcommerce in the name
|
|
8
|
+
* and stop there, not checking children.
|
|
9
|
+
*/
|
|
10
|
+
export declare function resolveDependenciesSync(root?: string): Map<string, string>;
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.resolveDependenciesSync = void 0;
|
|
7
|
+
const node_fs_1 = __importDefault(require("node:fs"));
|
|
8
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
9
|
+
function resolveRecursivePackageJson(packageJsonFilename, packageNames) {
|
|
10
|
+
try {
|
|
11
|
+
const packageJsonFile = node_fs_1.default.readFileSync(packageJsonFilename, 'utf-8').toString();
|
|
12
|
+
const packageJson = JSON.parse(packageJsonFile);
|
|
13
|
+
if (!packageJson.name)
|
|
14
|
+
throw Error('Package does not have a name');
|
|
15
|
+
const dependencies = [
|
|
16
|
+
...Object.keys(packageJson.dependencies ?? {}),
|
|
17
|
+
...Object.keys(packageJson.devDependencies ?? {}),
|
|
18
|
+
...Object.keys(packageJson.peerDependencies ?? {}),
|
|
19
|
+
];
|
|
20
|
+
const isGraphCommerce = !!dependencies.some((name) => name.includes('graphcommerce'));
|
|
21
|
+
if (!isGraphCommerce)
|
|
22
|
+
return packageNames;
|
|
23
|
+
const dirName = node_path_1.default.dirname(node_path_1.default.relative(process.cwd(), packageJsonFilename));
|
|
24
|
+
if (packageNames.has(packageJson.name))
|
|
25
|
+
return packageNames;
|
|
26
|
+
// Package not found, recursively scan
|
|
27
|
+
packageNames.set(packageJson.name, dirName);
|
|
28
|
+
dependencies.map((dependency) => {
|
|
29
|
+
try {
|
|
30
|
+
const filePath = require.resolve(node_path_1.default.join(dependency, 'package.json'));
|
|
31
|
+
if (filePath)
|
|
32
|
+
return resolveRecursivePackageJson(filePath, packageNames);
|
|
33
|
+
}
|
|
34
|
+
catch {
|
|
35
|
+
return false;
|
|
36
|
+
}
|
|
37
|
+
return false;
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
catch (e) {
|
|
41
|
+
// File is not a JSON file or something like that, we now skip this file
|
|
42
|
+
}
|
|
43
|
+
return packageNames;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* This will return a list of all dependencies that have `graphcommerce` in the name, matching:
|
|
47
|
+
*
|
|
48
|
+
* - `@graphcommerce/package-name`
|
|
49
|
+
* - `@mycompany/graphcommerce-my-feature`
|
|
50
|
+
*
|
|
51
|
+
* It will traverse children until it finds a package that doesn't contain graphcommerce in the name
|
|
52
|
+
* and stop there, not checking children.
|
|
53
|
+
*/
|
|
54
|
+
function resolveDependenciesSync(root = process.cwd()) {
|
|
55
|
+
return resolveRecursivePackageJson(node_path_1.default.join(root, 'package.json'), new Map());
|
|
56
|
+
}
|
|
57
|
+
exports.resolveDependenciesSync = resolveDependenciesSync;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { NextConfig } from 'next';
|
|
2
|
+
export declare type GraphCommerceConfig = {
|
|
3
|
+
/** Additional packages that should be transpiled, usually this auto generated. */
|
|
4
|
+
packages?: string[];
|
|
5
|
+
};
|
|
6
|
+
export declare function withGraphCommerce(conf?: GraphCommerceConfig): (config: NextConfig) => NextConfig;
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.withGraphCommerce = void 0;
|
|
7
|
+
const next_transpile_modules_1 = __importDefault(require("next-transpile-modules"));
|
|
8
|
+
const webpack_1 = require("webpack");
|
|
9
|
+
const resolveDependenciesSync_1 = require("./utils/resolveDependenciesSync");
|
|
10
|
+
function extendConfig(nextConfig, modules) {
|
|
11
|
+
return {
|
|
12
|
+
...nextConfig,
|
|
13
|
+
webpack: (config, options) => {
|
|
14
|
+
// Allow importing yml/yaml files for graphql-mesh
|
|
15
|
+
config.module?.rules?.push({ test: /\.ya?ml$/, use: 'js-yaml-loader' });
|
|
16
|
+
// To properly properly treeshake @apollo/client we need to define the __DEV__ property
|
|
17
|
+
if (!options.isServer) {
|
|
18
|
+
config.plugins = [new webpack_1.DefinePlugin({ __DEV__: options.dev }), ...(config.plugins ?? [])];
|
|
19
|
+
}
|
|
20
|
+
// @lingui .po file support
|
|
21
|
+
config.module?.rules?.push({ test: /\.po/, use: '@lingui/loader' });
|
|
22
|
+
config.experiments = {
|
|
23
|
+
layers: true,
|
|
24
|
+
topLevelAwait: true,
|
|
25
|
+
};
|
|
26
|
+
config.snapshot = {
|
|
27
|
+
...(config.snapshot ?? {}),
|
|
28
|
+
managedPaths: [new RegExp(`^(.+?[\\/]node_modules[\\/])(?!${modules.join('|')})`)],
|
|
29
|
+
};
|
|
30
|
+
// `config.watchOptions.ignored = ['**/.git/**', '**/node_modules/**', '**/.next/**']
|
|
31
|
+
config.watchOptions = {
|
|
32
|
+
...(config.watchOptions ?? {}),
|
|
33
|
+
ignored: ['**/.git/**', `**/node_modules/!(${modules.join('|')})**`, '**/.next/**'],
|
|
34
|
+
};
|
|
35
|
+
if (!config.resolve)
|
|
36
|
+
config.resolve = {};
|
|
37
|
+
config.resolve.alias = {
|
|
38
|
+
...config.resolve.alias,
|
|
39
|
+
'@mui/base': '@mui/base/modern',
|
|
40
|
+
'@mui/lab': '@mui/lab/modern',
|
|
41
|
+
'@mui/material': '@mui/material/modern',
|
|
42
|
+
'@mui/styled-engine': '@mui/styled-engine/modern',
|
|
43
|
+
'@mui/system': '@mui/system/modern',
|
|
44
|
+
};
|
|
45
|
+
return typeof nextConfig.webpack === 'function' ? nextConfig.webpack(config, options) : config;
|
|
46
|
+
},
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
function withGraphCommerce(conf = {}) {
|
|
50
|
+
const { packages = [] } = conf;
|
|
51
|
+
const dependencies = [...(0, resolveDependenciesSync_1.resolveDependenciesSync)().keys()];
|
|
52
|
+
const modules = [...dependencies, ...packages];
|
|
53
|
+
return (config) => extendConfig((0, next_transpile_modules_1.default)(modules)(config), modules);
|
|
54
|
+
}
|
|
55
|
+
exports.withGraphCommerce = withGraphCommerce;
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "@graphcommerce/next-config",
|
|
3
3
|
"homepage": "https://www.graphcommerce.org/",
|
|
4
4
|
"repository": "github:graphcommerce-org/graphcommerce",
|
|
5
|
-
"version": "
|
|
5
|
+
"version": "4.30.0-canary.0",
|
|
6
6
|
"type": "commonjs",
|
|
7
7
|
"main": "dist/index.js",
|
|
8
8
|
"typings": "dist/index.d.ts",
|
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
"prepack": "yarn build"
|
|
14
14
|
},
|
|
15
15
|
"dependencies": {
|
|
16
|
+
"@graphcommerce/cli": "4.30.0-canary.0",
|
|
16
17
|
"@lingui/loader": "^3.14.0",
|
|
17
18
|
"js-yaml-loader": "^1.2.2",
|
|
18
19
|
"next-transpile-modules": "^9.0.0",
|
package/src/index.ts
CHANGED
|
@@ -1,164 +1,14 @@
|
|
|
1
|
-
import { execSync } from 'child_process'
|
|
2
|
-
import { createHash } from 'crypto'
|
|
3
|
-
import { readFileSync, writeFileSync, mkdirSync } from 'fs'
|
|
4
|
-
import withTranspileModules from 'next-transpile-modules'
|
|
5
1
|
import { NextConfig } from 'next/dist/server/config-shared'
|
|
6
|
-
import
|
|
7
|
-
import { DefinePlugin, Configuration } from 'webpack'
|
|
2
|
+
import { withGraphCommerce } from './withGraphCommerce'
|
|
8
3
|
|
|
9
|
-
export
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
workspaceDependencies: string[]
|
|
13
|
-
mismatchedWorkspaceDependencies: string[]
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
type TreeNode = {
|
|
18
|
-
name: string
|
|
19
|
-
children?: TreeNode[]
|
|
20
|
-
hint: null
|
|
21
|
-
depth: number
|
|
22
|
-
color?: string
|
|
23
|
-
shadow?: boolean
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
export type ListInfo = {
|
|
27
|
-
type: 'tree'
|
|
28
|
-
data: {
|
|
29
|
-
type: 'list'
|
|
30
|
-
trees: TreeNode[]
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
function extendConfig(nextConfig: NextConfig): NextConfig {
|
|
35
|
-
return {
|
|
36
|
-
...nextConfig,
|
|
37
|
-
webpack: (config: Configuration, options) => {
|
|
38
|
-
// Allow importing yml/yaml files for graphql-mesh
|
|
39
|
-
config.module?.rules?.push({ test: /\.ya?ml$/, use: 'js-yaml-loader' })
|
|
40
|
-
|
|
41
|
-
// To properly properly treeshake @apollo/client we need to define the __DEV__ property
|
|
42
|
-
if (!options.isServer) {
|
|
43
|
-
config.plugins = [new DefinePlugin({ __DEV__: options.dev }), ...(config.plugins ?? [])]
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
// @lingui .po file support
|
|
47
|
-
config.module?.rules?.push({ test: /\.po/, use: '@lingui/loader' })
|
|
48
|
-
|
|
49
|
-
config.experiments = {
|
|
50
|
-
layers: true,
|
|
51
|
-
topLevelAwait: true,
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
config.snapshot = {
|
|
55
|
-
...(config.snapshot ?? {}),
|
|
56
|
-
managedPaths: [/^(.+?[\\/]node_modules[\\/])(?!@graphcommerce)/],
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
// `config.watchOptions.ignored = ['**/.git/**', '**/node_modules/**', '**/.next/**']
|
|
60
|
-
// Replace the '**/node_modules/**' with a regex that excludes node_modules except @graphcommerce
|
|
61
|
-
config.watchOptions = {
|
|
62
|
-
...(config.watchOptions ?? {}),
|
|
63
|
-
ignored: ['**/.git/**', '**/node_modules/!(@graphcommerce)**', '**/.next/**'],
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
if (!config.resolve) config.resolve = {}
|
|
67
|
-
config.resolve.alias = {
|
|
68
|
-
...config.resolve.alias,
|
|
69
|
-
'@mui/base': '@mui/base/modern',
|
|
70
|
-
'@mui/lab': '@mui/lab/modern',
|
|
71
|
-
'@mui/material': '@mui/material/modern',
|
|
72
|
-
'@mui/styled-engine': '@mui/styled-engine/modern',
|
|
73
|
-
'@mui/system': '@mui/system/modern',
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
return typeof nextConfig.webpack === 'function' ? nextConfig.webpack(config, options) : config
|
|
77
|
-
},
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
export function withYarn1Scopes(
|
|
82
|
-
scopes: string[] = ['@graphcommerce'],
|
|
83
|
-
): (config: NextConfig) => NextConfig {
|
|
84
|
-
const packageStr = readFileSync('package.json', 'utf-8')
|
|
4
|
+
export * from './utils/isMonorepo'
|
|
5
|
+
export * from './utils/resolveDependenciesSync'
|
|
6
|
+
export * from './withGraphCommerce'
|
|
85
7
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
const cacheKey = `.next/cache/withYarn1Scopes.${hashSum}.json`
|
|
89
|
-
let modules: string[]
|
|
90
|
-
try {
|
|
91
|
-
modules = JSON.parse(readFileSync(cacheKey, 'utf-8')) as string[]
|
|
92
|
-
} catch (e) {
|
|
93
|
-
const infoJson: string = execSync('yarn list --json', { encoding: 'utf-8' })
|
|
94
|
-
|
|
95
|
-
const workspaceInfo = JSON.parse(infoJson) as ListInfo
|
|
96
|
-
|
|
97
|
-
const list: Set<string> = new Set()
|
|
98
|
-
const walk = (node: TreeNode) => {
|
|
99
|
-
let packageName: string
|
|
100
|
-
if (node.name.includes('/')) {
|
|
101
|
-
const [scope, nameWithVersion] = node.name.split('/')
|
|
102
|
-
const [name] = nameWithVersion.split('@')
|
|
103
|
-
packageName = `${scope}/${name}`
|
|
104
|
-
} else {
|
|
105
|
-
const [name] = node.name.split('@')
|
|
106
|
-
packageName = `${name}`
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
const found = scopes.find((scope) => packageName.startsWith(scope))
|
|
110
|
-
if (found) list.add(packageName)
|
|
111
|
-
|
|
112
|
-
node.children?.forEach(walk)
|
|
113
|
-
}
|
|
114
|
-
workspaceInfo.data.trees.map(walk)
|
|
115
|
-
|
|
116
|
-
modules = [...list.values()]
|
|
117
|
-
|
|
118
|
-
mkdirSync('.next/cache/', { recursive: true })
|
|
119
|
-
writeFileSync(cacheKey, JSON.stringify(modules))
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
return (config) => extendConfig(withTranspileModules(modules)(config))
|
|
8
|
+
export function withYarn1Workspaces(packages: string[] = []): (config: NextConfig) => NextConfig {
|
|
9
|
+
return withGraphCommerce({ packages })
|
|
123
10
|
}
|
|
124
11
|
|
|
125
|
-
export function
|
|
126
|
-
|
|
127
|
-
const packageJson = JSON.parse(packageStr) as PackageJson
|
|
128
|
-
|
|
129
|
-
const hashSum = createHash('sha256').update(packageStr, 'utf-8').digest('hex').slice(0, 10)
|
|
130
|
-
|
|
131
|
-
let infoJson: string
|
|
132
|
-
const cacheKey = `.next/cache/withYarn1Workspaces.${hashSum}.json`
|
|
133
|
-
try {
|
|
134
|
-
infoJson = readFileSync(cacheKey, 'utf-8')
|
|
135
|
-
} catch (e) {
|
|
136
|
-
infoJson = execSync('yarn list info --json', { encoding: 'utf-8' })
|
|
137
|
-
try {
|
|
138
|
-
mkdirSync('.next/cache/', { recursive: true })
|
|
139
|
-
writeFileSync(cacheKey, infoJson)
|
|
140
|
-
} catch (er) {
|
|
141
|
-
// do nothing
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
|
146
|
-
const workspaceInfo = JSON.parse(JSON.parse(infoJson).data) as WorkspaceInfo
|
|
147
|
-
|
|
148
|
-
const requestedPackages = [
|
|
149
|
-
...Object.keys(packageJson.dependencies ?? {}),
|
|
150
|
-
...Object.keys(packageJson.devDependencies ?? {}),
|
|
151
|
-
]
|
|
152
|
-
|
|
153
|
-
const entries = Object.entries(workspaceInfo as unknown as WorkspaceInfo)
|
|
154
|
-
|
|
155
|
-
const m = new Set<string>(modules)
|
|
156
|
-
entries.forEach(([p, b]) => {
|
|
157
|
-
if (requestedPackages.includes(p)) {
|
|
158
|
-
m.add(p)
|
|
159
|
-
b.workspaceDependencies.forEach((wp) => m.add(wp))
|
|
160
|
-
}
|
|
161
|
-
})
|
|
162
|
-
|
|
163
|
-
return (config) => extendConfig(withTranspileModules([...m.values()])(config))
|
|
12
|
+
export function withYarn1Scopes(packages?: string[]): (config: NextConfig) => NextConfig {
|
|
13
|
+
return withGraphCommerce({ packages })
|
|
164
14
|
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import path from 'node:path'
|
|
2
|
+
|
|
3
|
+
export function isMonorepo() {
|
|
4
|
+
const root = process.cwd()
|
|
5
|
+
const meshDir = path.dirname(require.resolve('@graphcommerce/graphql-mesh'))
|
|
6
|
+
const relativePath = path.join(path.relative(meshDir, root), '/')
|
|
7
|
+
return relativePath.startsWith(`..${path.sep}..${path.sep}examples`)
|
|
8
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import fs from 'node:fs'
|
|
2
|
+
import path from 'node:path'
|
|
3
|
+
import type { PackageJson } from 'type-fest'
|
|
4
|
+
|
|
5
|
+
function resolveRecursivePackageJson(
|
|
6
|
+
packageJsonFilename: string,
|
|
7
|
+
packageNames: Map<string, string>,
|
|
8
|
+
) {
|
|
9
|
+
try {
|
|
10
|
+
const packageJsonFile = fs.readFileSync(packageJsonFilename, 'utf-8').toString()
|
|
11
|
+
|
|
12
|
+
const packageJson = JSON.parse(packageJsonFile) as PackageJson
|
|
13
|
+
|
|
14
|
+
if (!packageJson.name) throw Error('Package does not have a name')
|
|
15
|
+
|
|
16
|
+
const dependencies = [
|
|
17
|
+
...Object.keys(packageJson.dependencies ?? {}),
|
|
18
|
+
...Object.keys(packageJson.devDependencies ?? {}),
|
|
19
|
+
...Object.keys(packageJson.peerDependencies ?? {}),
|
|
20
|
+
]
|
|
21
|
+
|
|
22
|
+
const isGraphCommerce = !!dependencies.some((name) => name.includes('graphcommerce'))
|
|
23
|
+
if (!isGraphCommerce) return packageNames
|
|
24
|
+
|
|
25
|
+
const dirName = path.dirname(path.relative(process.cwd(), packageJsonFilename))
|
|
26
|
+
|
|
27
|
+
if (packageNames.has(packageJson.name)) return packageNames
|
|
28
|
+
|
|
29
|
+
// Package not found, recursively scan
|
|
30
|
+
packageNames.set(packageJson.name, dirName)
|
|
31
|
+
|
|
32
|
+
dependencies.map((dependency) => {
|
|
33
|
+
try {
|
|
34
|
+
const filePath = require.resolve(path.join(dependency, 'package.json'))
|
|
35
|
+
if (filePath) return resolveRecursivePackageJson(filePath, packageNames)
|
|
36
|
+
} catch {
|
|
37
|
+
return false
|
|
38
|
+
}
|
|
39
|
+
return false
|
|
40
|
+
})
|
|
41
|
+
} catch (e) {
|
|
42
|
+
// File is not a JSON file or something like that, we now skip this file
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
return packageNames
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* This will return a list of all dependencies that have `graphcommerce` in the name, matching:
|
|
50
|
+
*
|
|
51
|
+
* - `@graphcommerce/package-name`
|
|
52
|
+
* - `@mycompany/graphcommerce-my-feature`
|
|
53
|
+
*
|
|
54
|
+
* It will traverse children until it finds a package that doesn't contain graphcommerce in the name
|
|
55
|
+
* and stop there, not checking children.
|
|
56
|
+
*/
|
|
57
|
+
export function resolveDependenciesSync(root = process.cwd()) {
|
|
58
|
+
return resolveRecursivePackageJson(path.join(root, 'package.json'), new Map())
|
|
59
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import type { NextConfig } from 'next'
|
|
2
|
+
import withTranspileModules from 'next-transpile-modules'
|
|
3
|
+
import { DefinePlugin, Configuration } from 'webpack'
|
|
4
|
+
import { resolveDependenciesSync } from './utils/resolveDependenciesSync'
|
|
5
|
+
|
|
6
|
+
function extendConfig(nextConfig: NextConfig, modules: string[]): NextConfig {
|
|
7
|
+
return {
|
|
8
|
+
...nextConfig,
|
|
9
|
+
webpack: (config: Configuration, options) => {
|
|
10
|
+
// Allow importing yml/yaml files for graphql-mesh
|
|
11
|
+
config.module?.rules?.push({ test: /\.ya?ml$/, use: 'js-yaml-loader' })
|
|
12
|
+
|
|
13
|
+
// To properly properly treeshake @apollo/client we need to define the __DEV__ property
|
|
14
|
+
if (!options.isServer) {
|
|
15
|
+
config.plugins = [new DefinePlugin({ __DEV__: options.dev }), ...(config.plugins ?? [])]
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
// @lingui .po file support
|
|
19
|
+
config.module?.rules?.push({ test: /\.po/, use: '@lingui/loader' })
|
|
20
|
+
|
|
21
|
+
config.experiments = {
|
|
22
|
+
layers: true,
|
|
23
|
+
topLevelAwait: true,
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
config.snapshot = {
|
|
27
|
+
...(config.snapshot ?? {}),
|
|
28
|
+
managedPaths: [new RegExp(`^(.+?[\\/]node_modules[\\/])(?!${modules.join('|')})`)],
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// `config.watchOptions.ignored = ['**/.git/**', '**/node_modules/**', '**/.next/**']
|
|
32
|
+
config.watchOptions = {
|
|
33
|
+
...(config.watchOptions ?? {}),
|
|
34
|
+
ignored: ['**/.git/**', `**/node_modules/!(${modules.join('|')})**`, '**/.next/**'],
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
if (!config.resolve) config.resolve = {}
|
|
38
|
+
config.resolve.alias = {
|
|
39
|
+
...config.resolve.alias,
|
|
40
|
+
'@mui/base': '@mui/base/modern',
|
|
41
|
+
'@mui/lab': '@mui/lab/modern',
|
|
42
|
+
'@mui/material': '@mui/material/modern',
|
|
43
|
+
'@mui/styled-engine': '@mui/styled-engine/modern',
|
|
44
|
+
'@mui/system': '@mui/system/modern',
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
return typeof nextConfig.webpack === 'function' ? nextConfig.webpack(config, options) : config
|
|
48
|
+
},
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export type GraphCommerceConfig = {
|
|
53
|
+
/** Additional packages that should be transpiled, usually this auto generated. */
|
|
54
|
+
packages?: string[]
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export function withGraphCommerce(
|
|
58
|
+
conf: GraphCommerceConfig = {},
|
|
59
|
+
): (config: NextConfig) => NextConfig {
|
|
60
|
+
const { packages = [] } = conf
|
|
61
|
+
const dependencies = [...resolveDependenciesSync().keys()]
|
|
62
|
+
|
|
63
|
+
const modules = [...dependencies, ...packages]
|
|
64
|
+
return (config) => extendConfig(withTranspileModules(modules)(config), modules)
|
|
65
|
+
}
|