@modern-js/storybook-builder 0.0.0-next-20230913035856
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/.eslintrc.js +7 -0
- package/.turbo/turbo-build.log +6 -0
- package/CHANGELOG.md +24 -0
- package/LICENSE +21 -0
- package/dist/cjs/addons/components/modern.js +65 -0
- package/dist/cjs/addons/constants.js +11 -0
- package/dist/cjs/addons/index.js +20 -0
- package/dist/cjs/addons/preset/preview.js +14 -0
- package/dist/cjs/addons/type.js +4 -0
- package/dist/cjs/addons/withPluginRuntime.js +20 -0
- package/dist/cjs/build.js +109 -0
- package/dist/cjs/core.js +40 -0
- package/dist/cjs/docgen/actualNameHandler.js +34 -0
- package/dist/cjs/docgen/index.js +74 -0
- package/dist/cjs/docgen/loader.js +37 -0
- package/dist/cjs/docgen/process.js +39 -0
- package/dist/cjs/index.js +35 -0
- package/dist/cjs/plugin-storybook.js +316 -0
- package/dist/cjs/preset.js +61 -0
- package/dist/cjs/types.js +11 -0
- package/dist/cjs/utils.js +142 -0
- package/dist/esm/addons/components/modern.js +44 -0
- package/dist/esm/addons/constants.js +1 -0
- package/dist/esm/addons/index.js +5 -0
- package/dist/esm/addons/preset/preview.js +4 -0
- package/dist/esm/addons/type.js +1 -0
- package/dist/esm/addons/withPluginRuntime.js +10 -0
- package/dist/esm/build.js +83 -0
- package/dist/esm/core.js +30 -0
- package/dist/esm/docgen/actualNameHandler.js +24 -0
- package/dist/esm/docgen/index.js +54 -0
- package/dist/esm/docgen/loader.js +26 -0
- package/dist/esm/docgen/process.js +28 -0
- package/dist/esm/index.js +6 -0
- package/dist/esm/plugin-storybook.js +296 -0
- package/dist/esm/preset.js +36 -0
- package/dist/esm/types.js +1 -0
- package/dist/esm/utils.js +95 -0
- package/dist/types/addons/components/modern.d.ts +5 -0
- package/dist/types/addons/constants.d.ts +1 -0
- package/dist/types/addons/index.d.ts +2 -0
- package/dist/types/addons/preset/preview.d.ts +1 -0
- package/dist/types/addons/type.d.ts +4 -0
- package/dist/types/addons/withPluginRuntime.d.ts +2 -0
- package/dist/types/build.d.ts +7 -0
- package/dist/types/core.d.ts +4 -0
- package/dist/types/docgen/actualNameHandler.d.ts +14 -0
- package/dist/types/docgen/index.d.ts +9 -0
- package/dist/types/docgen/loader.d.ts +2 -0
- package/dist/types/docgen/process.d.ts +10 -0
- package/dist/types/index.d.ts +3 -0
- package/dist/types/plugin-storybook.d.ts +6 -0
- package/dist/types/preset.d.ts +6 -0
- package/dist/types/types.d.ts +15 -0
- package/dist/types/utils.d.ts +12 -0
- package/index.js +24 -0
- package/modern.config.js +5 -0
- package/package.json +96 -0
- package/src/addons/components/modern.tsx +52 -0
- package/src/addons/constants.ts +1 -0
- package/src/addons/index.ts +8 -0
- package/src/addons/preset/preview.ts +3 -0
- package/src/addons/type.ts +4 -0
- package/src/addons/withPluginRuntime.ts +18 -0
- package/src/build.ts +119 -0
- package/src/core.ts +51 -0
- package/src/docgen/actualNameHandler.ts +57 -0
- package/src/docgen/index.ts +100 -0
- package/src/docgen/loader.ts +34 -0
- package/src/docgen/process.ts +44 -0
- package/src/index.ts +7 -0
- package/src/plugin-storybook.ts +462 -0
- package/src/preset.ts +59 -0
- package/src/types.ts +21 -0
- package/src/utils.ts +131 -0
- package/templates/preview.ejs +54 -0
- package/templates/virtualModuleModernEntry.js.handlebars +43 -0
- package/tsconfig.json +16 -0
package/dist/esm/core.js
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
import { createBuilder, mergeBuilderConfig } from "@modern-js/builder";
|
2
|
+
import { loadConfig } from "@modern-js/core";
|
3
|
+
import { getProvider, runWithErrorMsg } from "./utils";
|
4
|
+
import { pluginStorybook } from "./plugin-storybook";
|
5
|
+
export async function getCompiler(cwd, frameworkConfig, options) {
|
6
|
+
const bundler = frameworkConfig.bundler || "webpack";
|
7
|
+
const { presets } = options;
|
8
|
+
const entries = await presets.apply("entries", []);
|
9
|
+
const res = await runWithErrorMsg(() => loadConfig(cwd, frameworkConfig.configPath || "modern.config.ts"), "Failed to load config");
|
10
|
+
const loadedConfig = res ? res.config : {};
|
11
|
+
const otherBuilderConfig = await presets.apply("modern", loadedConfig) || {};
|
12
|
+
const builderConfig = mergeBuilderConfig(otherBuilderConfig, loadedConfig);
|
13
|
+
const provider = await getProvider(bundler, builderConfig);
|
14
|
+
if (!provider) {
|
15
|
+
throw new Error(`@modern-js/builder-${bundler}-provider not found `);
|
16
|
+
}
|
17
|
+
const builder = await createBuilder(provider, {
|
18
|
+
cwd,
|
19
|
+
target: "web",
|
20
|
+
framework: "modern.js storybook",
|
21
|
+
entry: {
|
22
|
+
main: entries
|
23
|
+
}
|
24
|
+
});
|
25
|
+
builder.addPlugins([
|
26
|
+
pluginStorybook(cwd, options),
|
27
|
+
...loadedConfig.builderPlugins || []
|
28
|
+
]);
|
29
|
+
return builder.createCompiler();
|
30
|
+
}
|
@@ -0,0 +1,24 @@
|
|
1
|
+
import { namedTypes as t } from "ast-types";
|
2
|
+
import { getNameOrValue, isReactForwardRefCall } from "react-docgen/dist/utils";
|
3
|
+
export default function actualNameHandler(documentation, path, importer) {
|
4
|
+
if (t.ClassDeclaration.check(path.node) || t.FunctionDeclaration.check(path.node)) {
|
5
|
+
documentation.set("actualName", getNameOrValue(path.get("id")));
|
6
|
+
} else if (t.ArrowFunctionExpression.check(path.node) || t.FunctionExpression.check(path.node) || isReactForwardRefCall(path, importer)) {
|
7
|
+
let currentPath = path;
|
8
|
+
while (currentPath.parent) {
|
9
|
+
if (t.VariableDeclarator.check(currentPath.parent.node)) {
|
10
|
+
documentation.set("actualName", getNameOrValue(currentPath.parent.get("id")));
|
11
|
+
return;
|
12
|
+
}
|
13
|
+
if (t.AssignmentExpression.check(currentPath.parent.node)) {
|
14
|
+
const leftPath = currentPath.parent.get("left");
|
15
|
+
if (t.Identifier.check(leftPath.node) || t.Literal.check(leftPath.node)) {
|
16
|
+
documentation.set("actualName", getNameOrValue(leftPath));
|
17
|
+
return;
|
18
|
+
}
|
19
|
+
}
|
20
|
+
currentPath = currentPath.parent;
|
21
|
+
}
|
22
|
+
documentation.set("actualName", "");
|
23
|
+
}
|
24
|
+
}
|
@@ -0,0 +1,54 @@
|
|
1
|
+
import { CHAIN_ID, logger } from "@modern-js/utils";
|
2
|
+
export async function applyDocgenWebpack(chain, options) {
|
3
|
+
const typescriptOptions = await options.presets.apply("typescript", {});
|
4
|
+
const { reactDocgen, reactDocgenTypescriptOptions } = typescriptOptions || {};
|
5
|
+
if (typeof reactDocgen !== "string") {
|
6
|
+
return;
|
7
|
+
}
|
8
|
+
if (reactDocgen === "react-docgen-typescript") {
|
9
|
+
const { ReactDocgenTypeScriptPlugin } = await import("@storybook/react-docgen-typescript-plugin");
|
10
|
+
chain.plugin("Storybook-docgen").use(ReactDocgenTypeScriptPlugin, [
|
11
|
+
{
|
12
|
+
...reactDocgenTypescriptOptions,
|
13
|
+
savePropValueAsString: true
|
14
|
+
}
|
15
|
+
]);
|
16
|
+
} else if (reactDocgen === "react-docgen") {
|
17
|
+
const loader = require.resolve("./loader");
|
18
|
+
const resolveOptions = chain.toConfig().resolve;
|
19
|
+
chain.module.rule(CHAIN_ID.RULE.JS).use(CHAIN_ID.USE.REACT_DOCGEN).loader(loader).options({
|
20
|
+
resolveOptions
|
21
|
+
}).after(CHAIN_ID.USE.BABEL).after(CHAIN_ID.USE.ESBUILD).after(CHAIN_ID.USE.SWC).end();
|
22
|
+
const tsRuls = chain.module.rule(CHAIN_ID.RULE.TS);
|
23
|
+
if (tsRuls.uses.values().length !== 0) {
|
24
|
+
tsRuls.use(CHAIN_ID.USE.REACT_DOCGEN).loader(loader).options({
|
25
|
+
resolveOptions
|
26
|
+
}).after(CHAIN_ID.USE.TS).after(CHAIN_ID.USE.ESBUILD).after(CHAIN_ID.USE.SWC).end();
|
27
|
+
}
|
28
|
+
}
|
29
|
+
}
|
30
|
+
export async function applyDocgenRspack(config, options) {
|
31
|
+
var _config, _config_module;
|
32
|
+
const typescriptOptions = await options.presets.apply("typescript", {});
|
33
|
+
const { reactDocgen } = typescriptOptions || {};
|
34
|
+
if (reactDocgen !== "react-docgen") {
|
35
|
+
if (reactDocgen !== false && reactDocgen !== void 0) {
|
36
|
+
logger.warn(`Rspack currently only support 'typescript.reactDocgen: react-docgen' for auto docs generation, but you specified ${reactDocgen}`);
|
37
|
+
}
|
38
|
+
return;
|
39
|
+
}
|
40
|
+
var _module;
|
41
|
+
(_module = (_config = config).module) !== null && _module !== void 0 ? _module : _config.module = {};
|
42
|
+
var _rules;
|
43
|
+
(_rules = (_config_module = config.module).rules) !== null && _rules !== void 0 ? _rules : _config_module.rules = [];
|
44
|
+
config.module.rules.push({
|
45
|
+
test: /\.(tsx?|jsx?)$/,
|
46
|
+
exclude: /node_modules/,
|
47
|
+
use: {
|
48
|
+
loader: require.resolve("./loader"),
|
49
|
+
options: {
|
50
|
+
resolveOptions: config.resolve
|
51
|
+
}
|
52
|
+
}
|
53
|
+
});
|
54
|
+
}
|
@@ -0,0 +1,26 @@
|
|
1
|
+
let tinyPoolPromise = null;
|
2
|
+
async function docLoader(source, map, data) {
|
3
|
+
const callback = this.async();
|
4
|
+
if (!tinyPoolPromise) {
|
5
|
+
tinyPoolPromise = import("tinypool").then(({ Tinypool }) => {
|
6
|
+
return new Tinypool({
|
7
|
+
filename: require.resolve("./process")
|
8
|
+
});
|
9
|
+
});
|
10
|
+
}
|
11
|
+
const tinyPool = await tinyPoolPromise;
|
12
|
+
const result = await tinyPool.run({
|
13
|
+
source,
|
14
|
+
map,
|
15
|
+
filename: this.resourcePath,
|
16
|
+
data
|
17
|
+
});
|
18
|
+
if (result) {
|
19
|
+
const [docgen, outputMap] = result;
|
20
|
+
callback(null, `${source}
|
21
|
+
${docgen}`, outputMap, data);
|
22
|
+
} else {
|
23
|
+
callback(null, source, map, data);
|
24
|
+
}
|
25
|
+
}
|
26
|
+
export default docLoader;
|
@@ -0,0 +1,28 @@
|
|
1
|
+
import { importers, resolver, handlers, parse } from "react-docgen";
|
2
|
+
import actualNameHandler from "./actualNameHandler";
|
3
|
+
const defaultHandlers = Object.values(handlers).map((handler) => handler);
|
4
|
+
const importer = importers.makeFsImporter();
|
5
|
+
export default ({ source, map, filename }) => {
|
6
|
+
try {
|
7
|
+
const results = parse(source, resolver.findAllExportedComponentDefinitions, [
|
8
|
+
...defaultHandlers,
|
9
|
+
actualNameHandler
|
10
|
+
], {
|
11
|
+
filename,
|
12
|
+
importer
|
13
|
+
});
|
14
|
+
const docgen = results.map((result) => {
|
15
|
+
const { actualName, ...docgenInfo } = result;
|
16
|
+
if (actualName) {
|
17
|
+
return `${actualName}.__docgenInfo=${JSON.stringify(docgenInfo)}`;
|
18
|
+
}
|
19
|
+
return "";
|
20
|
+
}).filter(Boolean).join(";");
|
21
|
+
return [
|
22
|
+
docgen,
|
23
|
+
map
|
24
|
+
];
|
25
|
+
} catch (e) {
|
26
|
+
return null;
|
27
|
+
}
|
28
|
+
};
|
@@ -0,0 +1,296 @@
|
|
1
|
+
import { isAbsolute, join, resolve } from "path";
|
2
|
+
import { slash, watch, globby } from "@modern-js/utils";
|
3
|
+
import { mergeBuilderConfig } from "@modern-js/builder-shared";
|
4
|
+
import { normalizeStories, stringifyProcessEnvs, handlebars, readTemplate, loadPreviewOrConfigFile } from "@storybook/core-common";
|
5
|
+
import { globals } from "@storybook/preview/globals";
|
6
|
+
import { unplugin as csfPlugin } from "@storybook/csf-plugin";
|
7
|
+
import { minimatch } from "minimatch";
|
8
|
+
import { toImportFn, virtualModule, maybeGetAbsolutePath } from "./utils";
|
9
|
+
import { applyDocgenRspack, applyDocgenWebpack } from "./docgen";
|
10
|
+
const STORIES_FILENAME = "storybook-stories.js";
|
11
|
+
const STORYBOOK_CONFIG_ENTRY = "storybook-config-entry.js";
|
12
|
+
const closeFn = [];
|
13
|
+
const onClose = (f) => {
|
14
|
+
closeFn.push(f);
|
15
|
+
};
|
16
|
+
export async function finalize() {
|
17
|
+
await Promise.all([
|
18
|
+
closeFn.map((close) => close())
|
19
|
+
]);
|
20
|
+
}
|
21
|
+
export const pluginStorybook = (cwd, options) => {
|
22
|
+
return {
|
23
|
+
name: "builder-plugin-storybook",
|
24
|
+
remove: [
|
25
|
+
"builder-plugin-inline"
|
26
|
+
],
|
27
|
+
async setup(api) {
|
28
|
+
const matchers = await options.presets.apply("stories", [], options);
|
29
|
+
const storyPatterns = normalizeStories(matchers, {
|
30
|
+
configDir: options.configDir,
|
31
|
+
workingDir: options.configDir
|
32
|
+
}).map(({ directory, files }) => {
|
33
|
+
const pattern = join(directory, files);
|
34
|
+
const absolutePattern = isAbsolute(pattern) ? pattern : join(options.configDir, pattern);
|
35
|
+
return absolutePattern;
|
36
|
+
});
|
37
|
+
api.modifyBuilderConfig(async (builderConfig) => {
|
38
|
+
await prepareStorybookModules(api.context.cachePath, cwd, options, builderConfig, storyPatterns);
|
39
|
+
await applyDefines(builderConfig, options);
|
40
|
+
await applyHTML(builderConfig, options);
|
41
|
+
await applyReact(builderConfig, options);
|
42
|
+
applyExternals(builderConfig);
|
43
|
+
});
|
44
|
+
const modifyConfig = async (config) => {
|
45
|
+
var _config;
|
46
|
+
var _resolve;
|
47
|
+
(_resolve = (_config = config).resolve) !== null && _resolve !== void 0 ? _resolve : _config.resolve = {};
|
48
|
+
config.resolve.conditionNames = [
|
49
|
+
"require",
|
50
|
+
"node",
|
51
|
+
...config.resolve.conditionNames || []
|
52
|
+
];
|
53
|
+
config.resolve.fullySpecified = false;
|
54
|
+
await applyMdxLoader(config, options);
|
55
|
+
await applyCsfPlugin(config, options);
|
56
|
+
};
|
57
|
+
if ("modifyWebpackConfig" in api) {
|
58
|
+
api.modifyWebpackConfig(modifyConfig);
|
59
|
+
api.modifyWebpackChain(async (chain) => {
|
60
|
+
await applyDocgenWebpack(chain, options);
|
61
|
+
});
|
62
|
+
} else if ("modifyRspackConfig" in api) {
|
63
|
+
api.modifyRspackConfig(async (config) => {
|
64
|
+
await modifyConfig(config);
|
65
|
+
await applyDocgenRspack(config, options);
|
66
|
+
});
|
67
|
+
}
|
68
|
+
}
|
69
|
+
};
|
70
|
+
};
|
71
|
+
async function applyCsfPlugin(config, options) {
|
72
|
+
var _addons_find;
|
73
|
+
var _config;
|
74
|
+
const { presets } = options;
|
75
|
+
const addons = await presets.apply("addons", []);
|
76
|
+
const { options: { bundler } } = await presets.apply("frameworkOptions");
|
77
|
+
var _addons_find_options;
|
78
|
+
const docsOptions = (_addons_find_options = (_addons_find = addons.find((a) => [
|
79
|
+
a,
|
80
|
+
a.name
|
81
|
+
].includes("@storybook/addon-docs"))) === null || _addons_find === void 0 ? void 0 : _addons_find.options) !== null && _addons_find_options !== void 0 ? _addons_find_options : {};
|
82
|
+
var _plugins;
|
83
|
+
(_plugins = (_config = config).plugins) !== null && _plugins !== void 0 ? _plugins : _config.plugins = [];
|
84
|
+
config.plugins.push(bundler === "rspack" ? csfPlugin.rspack(docsOptions) : csfPlugin.webpack(docsOptions));
|
85
|
+
}
|
86
|
+
async function prepareStorybookModules(tempDir, cwd, options, builderConfig, storyPatterns) {
|
87
|
+
var _builderConfig;
|
88
|
+
const mappings = await createStorybookModules(cwd, options, storyPatterns);
|
89
|
+
const componentsPath = maybeGetAbsolutePath(`@storybook/components`);
|
90
|
+
const routerPath = maybeGetAbsolutePath(`@storybook/router`);
|
91
|
+
const themingPath = maybeGetAbsolutePath(`@storybook/theming`);
|
92
|
+
const storybookPaths = {
|
93
|
+
...componentsPath ? {
|
94
|
+
[`@storybook/components`]: componentsPath
|
95
|
+
} : {},
|
96
|
+
...routerPath ? {
|
97
|
+
[`@storybook/router`]: routerPath
|
98
|
+
} : {},
|
99
|
+
...themingPath ? {
|
100
|
+
[`@storybook/theming`]: themingPath
|
101
|
+
} : {}
|
102
|
+
};
|
103
|
+
const [mappingsAlias, write] = await virtualModule(tempDir, cwd, mappings);
|
104
|
+
var _source;
|
105
|
+
(_source = (_builderConfig = builderConfig).source) !== null && _source !== void 0 ? _source : _builderConfig.source = {};
|
106
|
+
builderConfig.source.alias = {
|
107
|
+
...builderConfig.source.alias,
|
108
|
+
...storybookPaths,
|
109
|
+
...mappingsAlias
|
110
|
+
};
|
111
|
+
const watcher = await watchStories(storyPatterns, cwd, write);
|
112
|
+
onClose(async () => {
|
113
|
+
await watcher.close();
|
114
|
+
});
|
115
|
+
}
|
116
|
+
async function applyDefines(builderConfig, options) {
|
117
|
+
var _builderConfig;
|
118
|
+
const { presets } = options;
|
119
|
+
const envs = await presets.apply("env");
|
120
|
+
var _source;
|
121
|
+
(_source = (_builderConfig = builderConfig).source) !== null && _source !== void 0 ? _source : _builderConfig.source = {};
|
122
|
+
builderConfig.source.define = {
|
123
|
+
...builderConfig.source.define,
|
124
|
+
...stringifyProcessEnvs(envs),
|
125
|
+
"process.env": JSON.stringify(envs),
|
126
|
+
NODE_ENV: JSON.stringify(process.env.NODE_ENV)
|
127
|
+
};
|
128
|
+
}
|
129
|
+
async function applyHTML(builderConfig, options) {
|
130
|
+
var _builderConfig;
|
131
|
+
const { presets, packageJson, configType, features, previewUrl, serverChannelUrl } = options;
|
132
|
+
const [coreOptions, frameworkOptions, logLevel, headHtmlSnippet, bodyHtmlSnippet, template, docsOptions] = await Promise.all([
|
133
|
+
presets.apply("core"),
|
134
|
+
presets.apply("frameworkOptions"),
|
135
|
+
presets.apply("logLevel", void 0),
|
136
|
+
presets.apply("previewHead"),
|
137
|
+
presets.apply("previewBody"),
|
138
|
+
presets.apply("previewMainTemplate"),
|
139
|
+
presets.apply("docs")
|
140
|
+
]);
|
141
|
+
var _tools;
|
142
|
+
(_tools = (_builderConfig = builderConfig).tools) !== null && _tools !== void 0 ? _tools : _builderConfig.tools = {};
|
143
|
+
builderConfig.tools.htmlPlugin = {
|
144
|
+
...builderConfig.tools.htmlPlugin,
|
145
|
+
template,
|
146
|
+
filename: "iframe.html",
|
147
|
+
templateParameters: {
|
148
|
+
...builderConfig.tools.htmlPlugin ? builderConfig.tools.htmlPlugin.templateParameters || {} : {},
|
149
|
+
version: packageJson.version || "",
|
150
|
+
globals: {
|
151
|
+
CONFIG_TYPE: configType,
|
152
|
+
LOGLEVEL: logLevel,
|
153
|
+
FRAMEWORK_OPTIONS: frameworkOptions,
|
154
|
+
CHANNEL_OPTIONS: coreOptions.channelOptions,
|
155
|
+
FEATURES: features,
|
156
|
+
PREVIEW_URL: previewUrl,
|
157
|
+
DOCS_OPTIONS: docsOptions,
|
158
|
+
SERVER_CHANNEL_URL: serverChannelUrl
|
159
|
+
},
|
160
|
+
headHtmlSnippet,
|
161
|
+
bodyHtmlSnippet
|
162
|
+
},
|
163
|
+
inject: false
|
164
|
+
};
|
165
|
+
}
|
166
|
+
async function applyMdxLoader(config, options) {
|
167
|
+
var _mdxPluginOptions, _mdxPluginOptions_mdxCompileOptions, _mdxPluginOptions1, _options_features;
|
168
|
+
var _config, _config_module;
|
169
|
+
const { presets, mdxPluginOptions } = options;
|
170
|
+
const remarkExternalLinks = await import("remark-external-links");
|
171
|
+
const remarkSlug = await import("remark-slug");
|
172
|
+
var _mdxPluginOptions_mdxCompileOptions_remarkPlugins;
|
173
|
+
const mdxLoaderOptions = await presets.apply("mdxLoaderOptions", {
|
174
|
+
skipCsf: true,
|
175
|
+
mdxCompileOptions: {
|
176
|
+
providerImportSource: "@storybook/addon-docs/mdx-react-shim",
|
177
|
+
...(_mdxPluginOptions = mdxPluginOptions) === null || _mdxPluginOptions === void 0 ? void 0 : _mdxPluginOptions.mdxCompileOptions,
|
178
|
+
remarkPlugins: [
|
179
|
+
remarkSlug,
|
180
|
+
remarkExternalLinks,
|
181
|
+
...(_mdxPluginOptions_mdxCompileOptions_remarkPlugins = (_mdxPluginOptions1 = mdxPluginOptions) === null || _mdxPluginOptions1 === void 0 ? void 0 : (_mdxPluginOptions_mdxCompileOptions = _mdxPluginOptions1.mdxCompileOptions) === null || _mdxPluginOptions_mdxCompileOptions === void 0 ? void 0 : _mdxPluginOptions_mdxCompileOptions.remarkPlugins) !== null && _mdxPluginOptions_mdxCompileOptions_remarkPlugins !== void 0 ? _mdxPluginOptions_mdxCompileOptions_remarkPlugins : []
|
182
|
+
]
|
183
|
+
}
|
184
|
+
});
|
185
|
+
const mdxLoader = ((_options_features = options.features) === null || _options_features === void 0 ? void 0 : _options_features.legacyMdx1) ? require.resolve("@storybook/mdx1-csf/loader") : require.resolve("@storybook/mdx2-csf/loader");
|
186
|
+
var _module;
|
187
|
+
(_module = (_config = config).module) !== null && _module !== void 0 ? _module : _config.module = {};
|
188
|
+
var _rules;
|
189
|
+
(_rules = (_config_module = config.module).rules) !== null && _rules !== void 0 ? _rules : _config_module.rules = [];
|
190
|
+
config.module.rules.push({
|
191
|
+
test: /(stories|story)\.mdx$/,
|
192
|
+
use: [
|
193
|
+
{
|
194
|
+
loader: mdxLoader,
|
195
|
+
options: {
|
196
|
+
...mdxLoaderOptions,
|
197
|
+
skipCsf: false
|
198
|
+
}
|
199
|
+
}
|
200
|
+
]
|
201
|
+
}, {
|
202
|
+
test: /\.mdx$/,
|
203
|
+
exclude: /(stories|story)\.mdx$/,
|
204
|
+
use: [
|
205
|
+
{
|
206
|
+
loader: mdxLoader,
|
207
|
+
options: mdxLoaderOptions
|
208
|
+
}
|
209
|
+
]
|
210
|
+
});
|
211
|
+
}
|
212
|
+
function applyExternals(builderConfig) {
|
213
|
+
var _builderConfig_output;
|
214
|
+
const config = mergeBuilderConfig({
|
215
|
+
output: {
|
216
|
+
externals: (_builderConfig_output = builderConfig.output) === null || _builderConfig_output === void 0 ? void 0 : _builderConfig_output.externals
|
217
|
+
}
|
218
|
+
}, {
|
219
|
+
output: {
|
220
|
+
externals: globals
|
221
|
+
}
|
222
|
+
});
|
223
|
+
builderConfig.output = config.output;
|
224
|
+
}
|
225
|
+
function getStoriesEntryPath(cwd) {
|
226
|
+
return resolve(join(cwd, STORIES_FILENAME));
|
227
|
+
}
|
228
|
+
function getStoriesConfigPath(cwd) {
|
229
|
+
return resolve(join(cwd, STORYBOOK_CONFIG_ENTRY));
|
230
|
+
}
|
231
|
+
async function createStorybookModules(cwd, options, storyPatterns) {
|
232
|
+
const virtualModuleMappings = {};
|
233
|
+
const { presets } = options;
|
234
|
+
const storiesEntry = await createStoriesEntry(cwd, storyPatterns);
|
235
|
+
virtualModuleMappings[getStoriesEntryPath(cwd)] = storiesEntry;
|
236
|
+
const configEntryPath = getStoriesConfigPath(cwd);
|
237
|
+
const previewAnnotations = [
|
238
|
+
...(await presets.apply("previewAnnotations", [], options)).map((entry) => {
|
239
|
+
if (typeof entry === "object") {
|
240
|
+
return entry.absolute;
|
241
|
+
}
|
242
|
+
return resolve(cwd, slash(entry));
|
243
|
+
}),
|
244
|
+
loadPreviewOrConfigFile(options)
|
245
|
+
].filter(Boolean);
|
246
|
+
virtualModuleMappings[configEntryPath] = handlebars(await readTemplate(require.resolve("@modern-js/storybook-builder/templates/virtualModuleModernEntry.js.handlebars")), {
|
247
|
+
storiesFilename: STORIES_FILENAME,
|
248
|
+
previewAnnotations
|
249
|
+
}).replace(/\\/g, "\\\\");
|
250
|
+
return virtualModuleMappings;
|
251
|
+
}
|
252
|
+
async function createStoriesEntry(cwd, storyPatterns) {
|
253
|
+
const stories = (await Promise.all(storyPatterns.map((pattern) => {
|
254
|
+
return globby(slash(pattern), {
|
255
|
+
followSymbolicLinks: true
|
256
|
+
});
|
257
|
+
}))).reduce((carry, stories2) => carry.concat(stories2), []);
|
258
|
+
return await toImportFn(cwd, stories);
|
259
|
+
}
|
260
|
+
async function applyReact(config, options) {
|
261
|
+
let version = "18.0.0";
|
262
|
+
try {
|
263
|
+
({ version } = await import("react-dom/package.json"));
|
264
|
+
} catch (_) {
|
265
|
+
}
|
266
|
+
const { legacyRootApi } = await options.presets.apply("frameworkOptions") || {};
|
267
|
+
const isReact18 = version.startsWith("18") || version.startsWith("0.0.0");
|
268
|
+
const useReact17 = legacyRootApi !== null && legacyRootApi !== void 0 ? legacyRootApi : !isReact18;
|
269
|
+
if (!useReact17) {
|
270
|
+
var _config, _config_source;
|
271
|
+
var _source;
|
272
|
+
(_source = (_config = config).source) !== null && _source !== void 0 ? _source : _config.source = {};
|
273
|
+
var _alias;
|
274
|
+
(_alias = (_config_source = config.source).alias) !== null && _alias !== void 0 ? _alias : _config_source.alias = {};
|
275
|
+
config.source.alias["@storybook/react-dom-shim"] = "@storybook/react-dom-shim/dist/react-18";
|
276
|
+
}
|
277
|
+
}
|
278
|
+
async function watchStories(patterns, cwd, writeModule) {
|
279
|
+
const watcher = watch(cwd, async ({ changeType, changedFilePath }) => {
|
280
|
+
if (changeType !== "add" && changeType !== "unlink") {
|
281
|
+
return;
|
282
|
+
}
|
283
|
+
if (patterns.some((entry) => minimatch(changedFilePath, entry))) {
|
284
|
+
const stories = (await Promise.all(patterns.map((pattern) => {
|
285
|
+
return globby(slash(pattern), {
|
286
|
+
followSymbolicLinks: true
|
287
|
+
});
|
288
|
+
}))).reduce((carry, stories2) => carry.concat(stories2), []);
|
289
|
+
const newStories = await toImportFn(cwd, stories);
|
290
|
+
writeModule(getStoriesEntryPath(cwd), newStories);
|
291
|
+
}
|
292
|
+
}, [
|
293
|
+
/node_modules/
|
294
|
+
]);
|
295
|
+
return watcher;
|
296
|
+
}
|
@@ -0,0 +1,36 @@
|
|
1
|
+
import { join, resolve } from "path";
|
2
|
+
import { getConfig } from "./build";
|
3
|
+
import { STORYBOOK_CONFIG_ENTRY } from "./utils";
|
4
|
+
export const previewMainTemplate = () => {
|
5
|
+
return require.resolve("@modern-js/storybook-builder/templates/preview.ejs");
|
6
|
+
};
|
7
|
+
function getStoriesConfigPath(cwd) {
|
8
|
+
return resolve(join(cwd, STORYBOOK_CONFIG_ENTRY));
|
9
|
+
}
|
10
|
+
export const entries = async (_, options) => {
|
11
|
+
const result = [];
|
12
|
+
const { bundler } = await getConfig(options);
|
13
|
+
if (options.configType === "DEVELOPMENT") {
|
14
|
+
result.push(...[
|
15
|
+
`${require.resolve("webpack-hot-middleware/client")}?reload=true&quiet=false&noInfo=${options.quiet}`,
|
16
|
+
bundler === "rspack" ? require.resolve("@rspack/dev-client/react-refresh-entry") : null
|
17
|
+
].filter(Boolean));
|
18
|
+
}
|
19
|
+
result.push(getStoriesConfigPath(process.cwd()));
|
20
|
+
return result;
|
21
|
+
};
|
22
|
+
export const modern = (builderConfig, options) => {
|
23
|
+
var _builderConfig_output;
|
24
|
+
return {
|
25
|
+
...builderConfig,
|
26
|
+
output: {
|
27
|
+
...builderConfig.output,
|
28
|
+
disableInlineRuntimeChunk: true,
|
29
|
+
distPath: {
|
30
|
+
...(_builderConfig_output = builderConfig.output) === null || _builderConfig_output === void 0 ? void 0 : _builderConfig_output.distPath,
|
31
|
+
root: options.outputDir
|
32
|
+
}
|
33
|
+
}
|
34
|
+
};
|
35
|
+
};
|
36
|
+
export { decorators } from "./addons/preset/preview";
|
@@ -0,0 +1 @@
|
|
1
|
+
export { defineConfig } from "@modern-js/builder/cli";
|
@@ -0,0 +1,95 @@
|
|
1
|
+
import path, { dirname, join } from "path";
|
2
|
+
import { createRequire } from "node:module";
|
3
|
+
import { fs, logger } from "@modern-js/utils";
|
4
|
+
export const VIRTUAL_MODULE_BASE = ".MODERN_STORYBOOK";
|
5
|
+
export const STORIES_FILENAME = "storybook-stories.js";
|
6
|
+
export const STORYBOOK_CONFIG_ENTRY = "storybook-config-entry.js";
|
7
|
+
export const requireResolve = (importer, path2) => {
|
8
|
+
const require1 = createRequire(importer);
|
9
|
+
require1.resolve(path2);
|
10
|
+
};
|
11
|
+
export async function getProvider(bundler, builderConfig) {
|
12
|
+
try {
|
13
|
+
if (bundler === "webpack") {
|
14
|
+
const { builderWebpackProvider } = await import("@modern-js/builder-webpack-provider");
|
15
|
+
return builderWebpackProvider({
|
16
|
+
builderConfig
|
17
|
+
});
|
18
|
+
} else {
|
19
|
+
const { builderRspackProvider } = await import("@modern-js/builder-rspack-provider");
|
20
|
+
return builderRspackProvider({
|
21
|
+
builderConfig
|
22
|
+
});
|
23
|
+
}
|
24
|
+
} catch (e) {
|
25
|
+
logger.error(`Cannot find provider, you need to install @modern-js/builder-${bundler}-provider first`);
|
26
|
+
}
|
27
|
+
}
|
28
|
+
export async function virtualModule(tempDir, cwd, virtualModuleMap) {
|
29
|
+
fs.ensureDirSync(tempDir);
|
30
|
+
const alias = {};
|
31
|
+
await Promise.all(Reflect.ownKeys(virtualModuleMap).map((k) => {
|
32
|
+
const virtualPath = k;
|
33
|
+
const relativePath = path.relative(cwd, virtualPath);
|
34
|
+
const realPath = path.join(tempDir, relativePath);
|
35
|
+
alias[virtualPath] = realPath;
|
36
|
+
return fs.writeFile(realPath, virtualModuleMap[virtualPath]);
|
37
|
+
}));
|
38
|
+
return [
|
39
|
+
alias,
|
40
|
+
(virtualPath, content) => {
|
41
|
+
const relativePath = path.relative(cwd, virtualPath);
|
42
|
+
const realPath = path.join(tempDir, relativePath);
|
43
|
+
fs.writeFileSync(realPath, content);
|
44
|
+
}
|
45
|
+
];
|
46
|
+
}
|
47
|
+
export async function toImportFn(cwd, stories) {
|
48
|
+
const objectEntries = stories.map((file) => {
|
49
|
+
const ext = path.extname(file);
|
50
|
+
const relativePath = path.relative(cwd, file);
|
51
|
+
if (![
|
52
|
+
".js",
|
53
|
+
".jsx",
|
54
|
+
".ts",
|
55
|
+
".tsx",
|
56
|
+
".mdx"
|
57
|
+
].includes(ext)) {
|
58
|
+
logger.warn(`Cannot process ${ext} file with storyStoreV7: ${relativePath}`);
|
59
|
+
}
|
60
|
+
return ` '${toImportPath(relativePath)}': async () => import('${file}')`;
|
61
|
+
});
|
62
|
+
return `
|
63
|
+
const importers = {
|
64
|
+
${objectEntries.join(",\n")}
|
65
|
+
};
|
66
|
+
|
67
|
+
export async function importFn(path) {
|
68
|
+
return importers[path]();
|
69
|
+
}
|
70
|
+
`;
|
71
|
+
}
|
72
|
+
function toImportPath(relativePath) {
|
73
|
+
return relativePath.startsWith("../") ? relativePath : `./${relativePath}`;
|
74
|
+
}
|
75
|
+
export function getAbsolutePath(input) {
|
76
|
+
return dirname(require.resolve(join(input, "package.json")));
|
77
|
+
}
|
78
|
+
export function maybeGetAbsolutePath(input) {
|
79
|
+
try {
|
80
|
+
return getAbsolutePath(input);
|
81
|
+
} catch (e) {
|
82
|
+
return false;
|
83
|
+
}
|
84
|
+
}
|
85
|
+
export async function runWithErrorMsg(op, msg) {
|
86
|
+
try {
|
87
|
+
return await op();
|
88
|
+
} catch (e) {
|
89
|
+
logger.error(msg);
|
90
|
+
console.error(e);
|
91
|
+
}
|
92
|
+
}
|
93
|
+
export function isDev() {
|
94
|
+
return process.env.NODE_ENV === "development";
|
95
|
+
}
|
@@ -0,0 +1,5 @@
|
|
1
|
+
/// <reference types="react" />
|
2
|
+
import type { Plugin } from '@modern-js/runtime';
|
3
|
+
import type { IConfig } from '../type';
|
4
|
+
export declare const WrapProviders: (storyFn: any, config: IConfig) => JSX.Element;
|
5
|
+
export declare const resolvePlugins: (runtime: IConfig['modernConfigRuntime']) => Plugin[];
|
@@ -0,0 +1 @@
|
|
1
|
+
export declare const ADDON_ID = "storybook/modern-runtime";
|
@@ -0,0 +1 @@
|
|
1
|
+
export declare const decorators: import("@storybook/types").DecoratorFunction[];
|
@@ -0,0 +1,7 @@
|
|
1
|
+
import type { Builder as RawStorybookBuilder, Stats } from '@storybook/types';
|
2
|
+
import type { FrameworkOptions } from './types';
|
3
|
+
export type StorybookBuilder = RawStorybookBuilder<FrameworkOptions, Stats>;
|
4
|
+
export declare const getConfig: StorybookBuilder['getConfig'];
|
5
|
+
export declare const build: StorybookBuilder['build'];
|
6
|
+
export declare const start: StorybookBuilder['start'];
|
7
|
+
export declare const bail: () => Promise<void>;
|
@@ -0,0 +1,4 @@
|
|
1
|
+
import type { Options } from '@storybook/types';
|
2
|
+
import type { Compiler } from '@modern-js/utils/webpack-dev-middleware';
|
3
|
+
import type { FrameworkOptions } from './types';
|
4
|
+
export declare function getCompiler(cwd: string, frameworkConfig: FrameworkOptions, options: Options): Promise<Compiler>;
|
@@ -0,0 +1,14 @@
|
|
1
|
+
/**
|
2
|
+
* This is heavily based on the react-docgen `displayNameHandler`
|
3
|
+
* (https://github.com/reactjs/react-docgen/blob/26c90c0dd105bf83499a83826f2a6ff7a724620d/src/handlers/displayNameHandler.ts)
|
4
|
+
* but instead defines an `actualName` property on the generated docs that is taken first from the component's actual name.
|
5
|
+
* This addresses an issue where the name that the generated docs are stored under is incorrectly named with the `displayName`
|
6
|
+
* and not the component's actual name.
|
7
|
+
*
|
8
|
+
* This is inspired by `actualNameHandler` from https://github.com/storybookjs/babel-plugin-react-docgen, but is modified
|
9
|
+
* directly from displayNameHandler, using the same approach as babel-plugin-react-docgen.
|
10
|
+
*/
|
11
|
+
import type { NodePath } from 'ast-types/lib/node-path';
|
12
|
+
import type { Importer } from 'react-docgen/dist/parse';
|
13
|
+
import type Documentation from 'react-docgen/dist/Documentation';
|
14
|
+
export default function actualNameHandler(documentation: Documentation, path: NodePath, importer: Importer): void;
|
@@ -0,0 +1,9 @@
|
|
1
|
+
import type { Options } from '@storybook/types';
|
2
|
+
import { RspackConfig } from '@modern-js/builder-rspack-provider';
|
3
|
+
import { WebpackChain } from '@modern-js/builder-webpack-provider';
|
4
|
+
export type DocgenOptions = {
|
5
|
+
reactDocgen?: 'react-docgen' | 'react-docgen-typescript' | false;
|
6
|
+
reactDocgenTypescriptOptions?: any;
|
7
|
+
};
|
8
|
+
export declare function applyDocgenWebpack(chain: WebpackChain, options: Options): Promise<void>;
|
9
|
+
export declare function applyDocgenRspack(config: RspackConfig, options: Options): Promise<void>;
|