Merge branch 'next' into shilman/add-web-components-vite-framework-and-template

This commit is contained in:
Michael Shilman 2022-09-27 10:48:10 +08:00
commit 584e2f0676
38 changed files with 1939 additions and 2044 deletions

View File

@ -51,7 +51,7 @@ executors:
default: 'medium'
working_directory: /tmp/storybook
docker:
- image: mcr.microsoft.com/playwright:v1.25.1-focal
- image: mcr.microsoft.com/playwright:v1.26.0-focal
environment:
NODE_OPTIONS: --max_old_space_size=3076
resource_class: <<parameters.class>>

View File

@ -60,7 +60,6 @@ describe('preview', () => {
it('should handle functions returning strings', () => {
const handler = linkTo(
// @ts-expect-error
(a, b) => a + b,
(a, b) => b + a
);

View File

@ -53,7 +53,10 @@ const valueOrCall = (args: string[]) => (value: string | ((...args: string[]) =>
typeof value === 'function' ? value(...args) : value;
export const linkTo =
(idOrTitle: string, nameInput?: string | ((...args: any[]) => string)) =>
(
idOrTitle: string | ((...args: any[]) => string),
nameInput?: string | ((...args: any[]) => string)
) =>
(...args: any[]) => {
const resolver = valueOrCall(args);
const title = resolver(idOrTitle);

View File

@ -1,3 +1,13 @@
<script>
import { createEventDispatcher } from 'svelte';
const dispatch = createEventDispatcher();
export let onClick = (event) => {
dispatch('click', event);
};
</script>
<div class="main">
<h1>Link Action</h1>
<button on:click={onClick} class="link">
@ -6,15 +16,4 @@
</div>
<style>
</style>
<script>
import { createEventDispatcher } from 'svelte';
const dispatch = createEventDispatcher();
function onClick(event) {
dispatch('click', event);
}
</script>

View File

@ -1,4 +1,3 @@
// @ts-nocheck
import { Component, EventEmitter, Input, Output } from '@angular/core';
export const exportedConstant = 'An exported constant';

View File

@ -1,3 +1,4 @@
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-nocheck
/* eslint-disable no-console */
/* eslint-disable no-underscore-dangle */

View File

@ -1,5 +1,4 @@
import global from 'global';
// @ts-ignore (FIXME should be expect-error no typedefs but fails build --prep)
import semver from '@storybook/semver';
import memoize from 'memoizerific';

View File

@ -1,2 +1,3 @@
declare module 'global';
declare module 'preval.macro';
declare module '@storybook/semver';

View File

@ -8,7 +8,7 @@ import { globalExternals } from '@fal-works/esbuild-plugin-global-externals';
import { pnpPlugin } from '@yarnpkg/esbuild-plugin-pnp';
import aliasPlugin from 'esbuild-plugin-alias';
import { renderHTML } from './utils/template';
import { getTemplatePath, renderHTML } from './utils/template';
import { definitions } from './utils/globals';
import {
BuilderBuildResult,
@ -28,9 +28,10 @@ export let compilation: Compilation;
let asyncIterator: ReturnType<StarterFunction> | ReturnType<BuilderFunction>;
export const getConfig: ManagerBuilder['getConfig'] = async (options) => {
const [addonsEntryPoints, customManagerEntryPoint] = await Promise.all([
const [addonsEntryPoints, customManagerEntryPoint, tsconfigPath] = await Promise.all([
options.presets.apply('managerEntries', []),
safeResolve(join(options.configDir, 'manager')),
getTemplatePath('addon.tsconfig.json'),
]);
return {
@ -57,6 +58,13 @@ export const getConfig: ManagerBuilder['getConfig'] = async (options) => {
minify: false,
sourcemap: true,
jsxFactory: 'React.createElement',
jsxFragment: 'React.Fragment',
jsx: 'transform',
jsxImportSource: 'react',
tsconfig: tsconfigPath,
legalComments: 'external',
plugins: [
aliasPlugin({

View File

@ -0,0 +1,6 @@
{
"compilerOptions": {
"jsx": "react",
"jsxImportSource": "react"
}
}

View File

@ -39,6 +39,9 @@ export async function generateIframeScriptCode(options: ExtendedOptions) {
addDecorator,
addParameters,
addLoader,
addArgs,
addArgTypes,
addStepRunner,
addArgTypesEnhancer,
addArgsEnhancer,
setGlobalRender,
@ -53,22 +56,10 @@ export async function generateIframeScriptCode(options: ExtendedOptions) {
const value = config[key];
switch (key) {
case 'args': {
if (typeof clientApi.addArgs !== "undefined") {
return clientApi.addArgs(value);
} else {
return logger.warn(
"Could not add global args. Please open an issue in storybookjs/builder-vite."
);
}
return addArgs(value);
}
case 'argTypes': {
if (typeof clientApi.addArgTypes !== "undefined") {
return clientApi.addArgTypes(value);
} else {
return logger.warn(
"Could not add global argTypes. Please open an issue in storybookjs/builder-vite."
);
}
return addArgTypes(value);
}
case 'decorators': {
return value.forEach((decorator) => addDecorator(decorator, false));
@ -99,6 +90,9 @@ export async function generateIframeScriptCode(options: ExtendedOptions) {
case 'renderToDOM': {
return null; // This key is not handled directly in v6 mode.
}
case 'runStep': {
return addStepRunner(value);
}
default: {
// eslint-disable-next-line prefer-template
return console.log(key + ' was not supported :( !');

View File

@ -73,6 +73,7 @@
"webpack-virtual-modules": "^0.4.3"
},
"devDependencies": {
"@types/case-sensitive-paths-webpack-plugin": "^2.1.6",
"@types/terser-webpack-plugin": "^5.2.0",
"@types/webpack-dev-middleware": "^5.3.0",
"@types/webpack-hot-middleware": "^2.25.6",

View File

@ -8,7 +8,7 @@ import { checkWebpackVersion } from '@storybook/core-webpack';
export * from './types';
let compilation: ReturnType<typeof webpackDevMiddleware>;
let compilation: ReturnType<typeof webpackDevMiddleware> | undefined;
let reject: (reason?: any) => void;
type WebpackBuilder = Builder<Configuration, Stats>;
@ -72,7 +72,6 @@ export const bail: WebpackBuilder['bail'] = async () => {
}
// we wait for the compiler to finish it's work, so it's command-line output doesn't interfere
return new Promise((res, rej) => {
// @ts-ignore (FIXME: should be expect-error but fails build --prep)
if (process && compilation) {
try {
compilation.close(() => res());
@ -134,7 +133,7 @@ const starter: StarterFunction = async function* starterGeneratorFn({
router.use(webpackHotMiddleware(compiler as any));
const stats = await new Promise<Stats>((ready, stop) => {
compilation.waitUntilValid(ready as any);
compilation?.waitUntilValid(ready as any);
reject = stop;
});
yield;
@ -219,10 +218,10 @@ const builder: BuilderFunction = async function* builderGeneratorFn({ startTime,
logger.trace({ message: '=> Preview built', time: process.hrtime(startTime) });
if (stats && stats.hasWarnings()) {
// @ts-ignore (FIXME should be @ts-expect-error but fails build --prep)
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- we know it has warnings because of hasWarnings()
stats
.toJson({ warnings: true } as StatsOptions)
.warnings.forEach((e) => logger.warn(e.message));
.warnings!.forEach((e) => logger.warn(e.message));
}
// https://webpack.js.org/api/node/#run

View File

@ -2,7 +2,6 @@ import path from 'path';
import { DefinePlugin, HotModuleReplacementPlugin, ProgressPlugin, ProvidePlugin } from 'webpack';
import type { Configuration } from 'webpack';
import HtmlWebpackPlugin from 'html-webpack-plugin';
// @ts-ignore
import CaseSensitivePathsPlugin from 'case-sensitive-paths-webpack-plugin';
import TerserWebpackPlugin from 'terser-webpack-plugin';
import VirtualModulePlugin from 'webpack-virtual-modules';

View File

@ -1,7 +1,8 @@
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"strict": true
"strict": true,
"skipLibCheck": true
},
"include": ["src/**/*", "typings.d.ts"],
"exclude": ["src/**.test.ts"]

View File

@ -28,15 +28,16 @@
/**
* Optional click handler
*/
function onClick(event) {
export let onClick = (event) => {
dispatch('click', event);
}
};
</script>
<button
type="button"
class={['storybook-button', `storybook-button--${size}`, mode].join(' ')}
{style}
on:click={onClick}>
on:click={onClick}
>
{label}
</button>

View File

@ -205,7 +205,7 @@ export async function baseGenerator(
: {}),
});
await configurePreview(renderer, options.commonJs);
await configurePreview(renderer);
if (addComponents) {
await copyComponents(renderer, language);

View File

@ -64,9 +64,9 @@ const frameworkToPreviewParts: Partial<Record<SupportedRenderers, any>> = {
},
};
export async function configurePreview(framework: SupportedRenderers, commonJs: boolean) {
export async function configurePreview(framework: SupportedRenderers) {
const { prefix = '', extraParameters = '' } = frameworkToPreviewParts[framework] || {};
const previewPath = `./.storybook/preview.${commonJs ? 'cjs' : 'js'}`;
const previewPath = `./.storybook/preview.js`;
// If the framework template included a preview then we have nothing to do
if (await fse.pathExists(previewPath)) {

View File

@ -148,17 +148,6 @@ export const angular13: Parameters = {
version: '13.1.x',
};
export const angular_modern_inline_rendering: Parameters = {
...baseAngular,
name: 'angular_modern_inline_rendering',
additionalDeps: ['jest@27', '@storybook/test-runner'],
mainOverrides: {
features: {
storyStoreV7: true,
},
},
};
export const angular: Parameters = baseAngular;
// #endregion

View File

@ -1,2 +1,3 @@
declare module 'pnp-webpack-plugin';
declare module '@storybook/semver';
declare module 'lazy-universal-dotenv';

View File

@ -1,4 +1,3 @@
// @ts-ignore (FIXME should be "@ts-expect-error does not have defs, but universal-dotenv is in TS now" but fails build --prep)
import { getEnvironment } from 'lazy-universal-dotenv';
import { nodePathsToArray } from './paths';

View File

@ -15,6 +15,7 @@ const DEFAULT_FILES = '**/*.@(mdx|stories.mdx|stories.tsx|stories.ts|stories.jsx
// TODO: remove - LEGACY support for bad glob patterns we had in SB 5 - remove in SB7
const fixBadGlob = deprecate(
(match: RegExpMatchArray) => {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore (FIXME should be "@ts-expect-error this will get removed later anyway" but fails build --prep)
return match.input.replace(match[1], `@${match[1]}`);
},

View File

@ -17,7 +17,7 @@ import { userOrAutoTitleFromSpecifier, sortStoriesV7 } from '@storybook/store';
import type { StoryIndexer, NormalizedStoriesSpecifier, DocsOptions } from '@storybook/core-common';
import { normalizeStoryPath } from '@storybook/core-common';
import { logger } from '@storybook/node-logger';
import { getStorySortParameter } from '@storybook/csf-tools';
import { getStorySortParameter, NoMetaError } from '@storybook/csf-tools';
import type { ComponentTitle, StoryName } from '@storybook/csf';
import { toId } from '@storybook/csf';
@ -235,7 +235,7 @@ export class StoryIndexGenerator {
}
}
} catch (err) {
if (err.name === 'NoMetaError') {
if (err instanceof NoMetaError) {
logger.info(`💡 Skipping ${relativePath}: ${err}`);
} else {
logger.warn(`🚨 Extraction error on ${relativePath}: ${err}`);

View File

@ -12,8 +12,7 @@ const config: Configuration = {
module: {
rules: [{ use: 'r1' }, { use: 'r2' }],
},
// For snapshot readability purposes `plugins` attribute doesn't match the correct type
// @ts-expect-errors
// @ts-expect-errors For snapshot readability purposes `plugins` attribute doesn't match the correct type
plugins: ['p1', 'p2'],
resolve: {
enforceExtension: true,
@ -45,8 +44,7 @@ describe('mergeConfigs', () => {
noParse: /jquery|lodash/,
rules: [{ use: 'r3' }, { use: 'r4' }],
},
// For snapshot readability purposes `plugins` attribute doesn't match the correct type
// @ts-expect-errors
// @ts-expect-errors For snapshot readability purposes `plugins` attribute doesn't match the correct type
plugins: ['p3', 'p4'],
resolve: {
enforceExtension: false,
@ -57,8 +55,7 @@ describe('mergeConfigs', () => {
},
},
optimization: {
// For snapshot readability purposes `minimizer` attribute doesn't match the correct type
// @ts-expect-errors
// @ts-expect-errors For snapshot readability purposes `minimizer` attribute doesn't match the correct type
minimizer: ['banana'],
},
};
@ -70,8 +67,7 @@ describe('mergeConfigs', () => {
it('merges partial custom config', () => {
const customConfig: Configuration = {
// For snapshot readability purposes `plugins` attribute doesn't match the correct type
// @ts-expect-errors
// @ts-expect-errors For snapshot readability purposes `plugins` attribute doesn't match the correct type
plugins: ['p3'],
resolve: {
extensions: ['.ts', '.tsx'],

View File

@ -20,9 +20,17 @@
},
"license": "MIT",
"sideEffects": false,
"main": "dist/cjs/index.js",
"module": "dist/esm/index.js",
"types": "dist/types/index.d.ts",
"exports": {
".": {
"require": "./dist/index.js",
"import": "./dist/index.mjs",
"types": "./dist/index.d.ts"
},
"./package.json": "./package.json"
},
"main": "dist/index.js",
"module": "dist/index.mjs",
"types": "dist/index.d.ts",
"files": [
"dist/**/*",
"README.md",
@ -31,7 +39,7 @@
],
"scripts": {
"check": "../../../scripts/node_modules/.bin/tsc --noEmit",
"prep": "node ../../../scripts/prepare.js"
"prep": "../../../scripts/prepare/bundle.ts"
},
"dependencies": {
"@babel/generator": "^7.12.11",
@ -39,7 +47,6 @@
"@babel/traverse": "^7.12.11",
"@babel/types": "^7.12.11",
"@storybook/csf": "0.0.2--canary.0899bb7.0",
"core-js": "^3.8.2",
"fs-extra": "^9.0.1",
"ts-dedent": "^2.0.0"
},
@ -51,5 +58,10 @@
"publishConfig": {
"access": "public"
},
"bundler": {
"entries": [
"./src/index.ts"
]
},
"gitHead": "5da5b0fabd04cc5cd5771e8242a960f05d03234a"
}

View File

@ -34,18 +34,6 @@ export type RenderPhase =
| 'aborted'
| 'errored';
function createController(): AbortController {
if (AbortController) return new AbortController();
// Polyfill for IE11
return {
signal: { aborted: false },
abort() {
// @ts-ignore (should be @ts-expect-error but fails build --prep)
this.signal.aborted = true;
},
} as AbortController;
}
function serializeError(error: any) {
try {
const { name = 'Error', message = String(error), stack } = error;
@ -88,7 +76,7 @@ export class StoryRender<TFramework extends AnyFramework> implements Render<TFra
public viewMode: ViewMode,
story?: Story<TFramework>
) {
this.abortController = createController();
this.abortController = new AbortController();
// Allow short-circuiting preparing if we happen to already
// have the story (this is used by docs mode)
@ -173,7 +161,7 @@ export class StoryRender<TFramework extends AnyFramework> implements Render<TFra
// render could conceivably still be running after this call.
// We might want to change that in the future.
this.cancelRender();
this.abortController = createController();
this.abortController = new AbortController();
}
// We need a stable reference to the signal -- if a re-mount happens the

View File

@ -130,7 +130,7 @@ export function handleADD(node, parent, storiesOfIdentifiers) {
return {};
}
if (storyName.value) {
if (storyName.value && typeof storyName.value === 'string') {
const key = sanitize(storyName.value);
let idToFramework;
if (key && framework) {

View File

@ -4,15 +4,14 @@ import path from 'path';
import shelljs from 'shelljs';
import { dedent } from 'ts-dedent';
const remove = (regex?: RegExp) => (input: string) =>
!(input === 'default' || (regex && regex.test(input)));
const remove = () => (input: string) => input !== 'default';
const location = path.join(__dirname, '..', 'src', 'globals', 'exports.ts');
const run = async () => {
const { values } = await import('../src/globals/runtime');
const data = Object.entries(values).reduce<Record<string, string[]>>((acc, [key, value]) => {
acc[key] = Object.keys(value).filter(remove(/^__/));
acc[key] = Object.keys(value).filter(remove());
return acc;
}, {});

View File

@ -11,6 +11,7 @@ export default {
'PureComponent',
'StrictMode',
'Suspense',
'__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED',
'cloneElement',
'createContext',
'createElement',
@ -33,6 +34,7 @@ export default {
'version',
],
'react-dom': [
'__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED',
'createPortal',
'findDOMNode',
'flushSync',

View File

@ -149,11 +149,10 @@
"@emotion/babel-plugin": "^11.10.2",
"@emotion/jest": "^11.10.0",
"@linear/sdk": "^1.21.0",
"@nicolo-ribaudo/chokidar-2": "^2.1.8",
"@nrwl/cli": "14.6.1",
"@nrwl/nx-cloud": "14.6.0",
"@nrwl/workspace": "14.6.1",
"@playwright/test": "^1.24.2",
"@playwright/test": "1.26.0",
"@rollup/plugin-babel": "^5.3.1",
"@rollup/plugin-commonjs": "^21.0.1",
"@rollup/plugin-json": "^4.1.0",
@ -325,7 +324,7 @@
"npmlog": "^5.0.1",
"nx": "14.6.1",
"p-limit": "^3.1.0",
"playwright": "^1.24.2",
"playwright": "1.26.0",
"postcss-loader": "^6.2.1",
"prettier": "2.7.1",
"process": "^0.11.10",

View File

@ -26,7 +26,7 @@ export const StoryIsUnrenderable = {
export const StoryContainsUnrenderable = {
render: () => (
<div>
{/* @ts-expect-error */}
{/* @ts-expect-error we're doing it wrong here on purpose */}
<BadComponent />
</div>
),

View File

@ -28,9 +28,9 @@
/**
* Optional click handler
*/
function onClick(event) {
export let onClick = (event) => {
dispatch('click', event);
}
};
</script>
<button

File diff suppressed because it is too large Load Diff

View File

@ -6,7 +6,7 @@ import { YourComponent } from './YourComponent';
//👇 This default export determines where your story goes in the story list
export default {
/* 👇 The title prop is optional.
* See https://storybook.js.org/docs/7.0/eact/configure/overview#configure-story-loading
* See https://storybook.js.org/docs/7.0/react/configure/overview#configure-story-loading
* to learn how to generate automatic titles
*/
title: 'YourComponent',

View File

@ -28,9 +28,9 @@
/**
* Optional click handler
*/
function onClick(event) {
export let onClick = (event) => {
dispatch('click', event);
}
};
</script>
<button type="button" {style} on:click="{onClick}">{label}</button>

View File

@ -2,7 +2,7 @@ module.exports = {
root: true,
extends: ['@storybook/eslint-config-storybook', 'plugin:storybook/recommended'],
rules: {
'@typescript-eslint/ban-ts-comment': 'warn',
'@typescript-eslint/ban-ts-comment': 'error',
'jest/no-standalone-expect': [
'error',
{ additionalTestBlockFunctions: ['it.skipWindows', 'it.onWindows'] },

View File

@ -57,7 +57,6 @@
"@emotion/jest": "^11.10.0",
"@jest/globals": "^26.6.2",
"@linear/sdk": "^1.21.0",
"@nicolo-ribaudo/chokidar-2": "^2.1.8",
"@nrwl/cli": "14.6.1",
"@nrwl/nx-cloud": "14.6.0",
"@nrwl/workspace": "14.6.1",

File diff suppressed because it is too large Load Diff