fix(storybook): linting react storybook files with eslint (#5146)
ISSUES CLOSED: #3867
This commit is contained in:
parent
ed94c4e1ec
commit
ec2ebca40a
@ -27,6 +27,20 @@ describe('Storybook schematics', () => {
|
||||
).toContain(`<title>Storybook</title>`);
|
||||
}, 1000000);
|
||||
|
||||
it('should lint a React based storybook without errors', () => {
|
||||
newProject();
|
||||
|
||||
const reactStorybookLib = uniq('test-ui-lib-react');
|
||||
runCLI(`generate @nrwl/react:lib ${reactStorybookLib} --no-interactive`);
|
||||
runCLI(
|
||||
`generate @nrwl/react:storybook-configuration ${reactStorybookLib} --generateStories --no-interactive`
|
||||
);
|
||||
|
||||
// build React lib
|
||||
const output = runCLI(`run ${reactStorybookLib}:lint`);
|
||||
expect(output).toContain('All files pass linting.');
|
||||
}, 1000000);
|
||||
|
||||
it('should build a React based storybook that references another lib', () => {
|
||||
const proj = newProject();
|
||||
|
||||
|
||||
@ -25,6 +25,11 @@
|
||||
"version": "11.0.12",
|
||||
"description": "Update storybook if installed and above 6",
|
||||
"factory": "./src/migrations/update-11-0-12/update-storybook"
|
||||
},
|
||||
"update-11-5-3": {
|
||||
"version": "11.5.3-beta.1",
|
||||
"description": "Update react storybook lint config",
|
||||
"factory": "./src/migrations/update-11-5-3/update-lint-ignores"
|
||||
}
|
||||
},
|
||||
"packageJsonUpdates": {
|
||||
|
||||
@ -4,5 +4,5 @@
|
||||
"emitDecoratorMetadata": true
|
||||
},
|
||||
"exclude": ["../**/*.spec.ts" <% if(uiFramework === '@storybook/react') { %>, "../**/*.spec.js", "../**/*.spec.tsx", "../**/*.spec.jsx"<% } %>],
|
||||
"include": ["../src/**/*"]
|
||||
"include": ["../src/**/*", "*.js"]
|
||||
}
|
||||
|
||||
@ -0,0 +1,58 @@
|
||||
import { Tree } from '@angular-devkit/schematics';
|
||||
import { getFileContent } from '@nrwl/workspace/testing';
|
||||
import { runMigration } from '../../utils/testing';
|
||||
|
||||
describe('Update 11-5-3', () => {
|
||||
let tree: Tree;
|
||||
|
||||
beforeEach(async () => {
|
||||
tree = Tree.empty();
|
||||
|
||||
// create workspace
|
||||
tree.create(
|
||||
'workspace.json',
|
||||
JSON.stringify({
|
||||
projects: {
|
||||
['home-ui-react']: {
|
||||
projectType: 'library',
|
||||
root: 'libs/home/ui-react',
|
||||
sourceRoot: 'libs/home/ui-react/src',
|
||||
architect: {
|
||||
storybook: {
|
||||
builder: '@nrwl/storybook:storybook',
|
||||
options: {
|
||||
uiFramework: '@storybook/react',
|
||||
port: 4400,
|
||||
config: {
|
||||
configFolder: 'libs/home/ui-react/.storybook',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
);
|
||||
|
||||
tree.create(
|
||||
'libs/home/ui-react/.storybook/tsconfig.json',
|
||||
JSON.stringify({
|
||||
extends: '../tsconfig.json',
|
||||
include: ['../src/**/*'],
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
it(`should add storybook tsconfig to lint target and update tsconfigs in project for React project`, async () => {
|
||||
tree = await runMigration('update-11-5-3', {}, tree);
|
||||
|
||||
expect(getFileContent(tree, 'libs/home/ui-react/.storybook/tsconfig.json'))
|
||||
.toMatchInlineSnapshot(`
|
||||
"{
|
||||
\\"extends\\": \\"../tsconfig.json\\",
|
||||
\\"include\\": [\\"../src/**/*\\", \\"./*.js\\"]
|
||||
}
|
||||
"
|
||||
`);
|
||||
});
|
||||
});
|
||||
@ -0,0 +1,94 @@
|
||||
import * as path from 'path';
|
||||
import {
|
||||
chain,
|
||||
Tree,
|
||||
SchematicContext,
|
||||
Rule,
|
||||
} from '@angular-devkit/schematics';
|
||||
|
||||
import {
|
||||
formatFiles,
|
||||
readJsonInTree,
|
||||
updateWorkspaceInTree,
|
||||
serializeJson,
|
||||
} from '@nrwl/workspace';
|
||||
|
||||
import { isFramework, TsConfig } from '../../utils/utilities';
|
||||
import { normalize } from '@angular-devkit/core';
|
||||
|
||||
interface ProjectDefinition {
|
||||
root: string;
|
||||
sourceRoot: string;
|
||||
projectType: 'library' | 'application';
|
||||
|
||||
schematic?: Record<string, any>;
|
||||
architect: Record<
|
||||
string,
|
||||
import('@angular-devkit/core').workspaces.TargetDefinition
|
||||
>;
|
||||
}
|
||||
|
||||
export default function (tree: Tree, context: SchematicContext) {
|
||||
return chain([update, formatFiles()]);
|
||||
}
|
||||
|
||||
function update(tree: Tree, context: SchematicContext): Rule {
|
||||
return updateWorkspaceInTree((config, context, tree) => {
|
||||
Object.entries<ProjectDefinition>(config.projects).forEach(
|
||||
([projectName, projectConfig]) => {
|
||||
updateTsconfigInclude(tree, context, { projectName, projectConfig });
|
||||
}
|
||||
);
|
||||
|
||||
return config;
|
||||
});
|
||||
}
|
||||
|
||||
function updateTsconfigInclude(
|
||||
tree: Tree,
|
||||
context: SchematicContext,
|
||||
options: {
|
||||
projectName: string;
|
||||
projectConfig: ProjectDefinition;
|
||||
}
|
||||
) {
|
||||
const architect = options.projectConfig.architect;
|
||||
|
||||
const paths = {
|
||||
tsConfigStorybook: normalize(
|
||||
path.join(options.projectConfig.root, '.storybook/tsconfig.json')
|
||||
),
|
||||
};
|
||||
|
||||
const hasStorybookConfig =
|
||||
architect.storybook && tree.exists(paths.tsConfigStorybook);
|
||||
|
||||
if (!hasStorybookConfig) {
|
||||
context.logger.info(
|
||||
`${options.projectName}: no storybook configured. skipping migration...`
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
const isReactProject = isFramework('react', {
|
||||
uiFramework: architect.storybook.options?.uiFramework as Parameters<
|
||||
typeof isFramework
|
||||
>[1]['uiFramework'],
|
||||
});
|
||||
|
||||
const tsConfig = {
|
||||
storybook: readJsonInTree<TsConfig>(tree, paths.tsConfigStorybook),
|
||||
};
|
||||
|
||||
if (isReactProject && Array.isArray(tsConfig.storybook.include)) {
|
||||
tsConfig.storybook.include = uniqueArray([
|
||||
...tsConfig.storybook.include,
|
||||
'./*.js',
|
||||
]);
|
||||
tree.overwrite(paths.tsConfigStorybook, serializeJson(tsConfig.storybook));
|
||||
}
|
||||
}
|
||||
|
||||
function uniqueArray<T extends Array<any>>(value: T) {
|
||||
return [...new Set(value)] as T;
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user