@nxext/stencil
Version:
Nx plugin for stenciljs
214 lines (212 loc) • 8.66 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.getProjectTsImportPath = getProjectTsImportPath;
exports.storybookConfigurationGenerator = storybookConfigurationGenerator;
exports.createProjectStorybookDir = createProjectStorybookDir;
exports.createRootStorybookDir = createRootStorybookDir;
const tslib_1 = require("tslib");
const devkit_1 = require("@nx/devkit");
const eslint_1 = require("@nx/eslint");
const js_1 = require("@nx/js");
const path_1 = require("path");
const utillities_1 = require("../../utils/utillities");
const add_dependencies_1 = require("./lib/add-dependencies");
const update_lint_config_1 = require("./lib/update-lint-config");
const get_npm_scope_1 = require("@nx/js/src/utils/package-json/get-npm-scope");
const ts_solution_setup_1 = require("@nx/js/src/utils/typescript/ts-solution-setup");
/**
* With Nx `npmScope` (eg: nx-workspace) and `projectName` (eg: nx-project), returns a path portion to be used for import statements or
* a tsconfig.json `paths` entry.
*
* @example `@nx-workspace/nx-project`
* @returns path portion of an import statement
*/
function getProjectTsImportPath(tree, projectName) {
const workspaceLayout = (0, devkit_1.getWorkspaceLayout)(tree);
const npmScope = (0, get_npm_scope_1.getNpmScope)(tree);
return `@${npmScope}/${projectName}`;
}
function storybookConfigurationGenerator(host, rawSchema) {
return tslib_1.__awaiter(this, void 0, void 0, function* () {
(0, ts_solution_setup_1.assertNotUsingTsSolutionSetup)(host, '@nxext/stencil', 'storybook-configuration');
const tasks = [];
const uiFramework = '@storybook/html-webpack5';
const options = normalizeSchema(rawSchema);
const projectConfig = (0, devkit_1.readProjectConfiguration)(host, options.name);
if (!(0, utillities_1.isBuildableStencilProject)(projectConfig)) {
devkit_1.logger.info((0, devkit_1.stripIndents) `
Please use a buildable library for storybook. Storybook needs a generated
Stencil loader to work (yet). They're working on native Stencil support, but
it's not ready yet.
You could make this library buildable with:
nx generate @nxext/stencil:make-lib-buildable ${options.name}
or
ng generate @nxext/stencil:make-lib-buildable ${options.name}
`);
return;
}
yield (0, devkit_1.ensurePackage)('@nx/storybook', devkit_1.NX_VERSION);
const { initGenerator } = yield Promise.resolve().then(() => require('@nx/storybook/src/generators/init/init'));
const initTask = yield initGenerator(host, {});
tasks.push(initTask);
createRootStorybookDir(host);
createProjectStorybookDir(host, options.name, uiFramework);
configureTsProjectConfig(host, options);
configureTsSolutionConfig(host);
(0, update_lint_config_1.updateLintConfig)(host, options);
addStorybookTask(host, options.name, uiFramework);
(0, add_dependencies_1.updateDependencies)(host);
if (options.configureCypress) {
yield (0, devkit_1.ensurePackage)('@nx/storybook', devkit_1.NX_VERSION);
const { cypressProjectGenerator } = yield Promise.resolve().then(() => require('@nx/storybook'));
if (projectConfig.projectType !== 'application') {
const cypressTask = yield cypressProjectGenerator(host, {
name: options.name,
js: false,
linter: options.linter,
directory: options.cypressDirectory,
standaloneConfig: options.standaloneConfig,
});
tasks.push(cypressTask);
}
else {
devkit_1.logger.warn('There is already an e2e project setup');
}
}
yield (0, devkit_1.formatFiles)(host);
return (0, devkit_1.runTasksInSerial)(...tasks);
});
}
function normalizeSchema(schema) {
const defaults = {
configureCypress: true,
linter: eslint_1.Linter.EsLint,
};
return Object.assign(Object.assign({}, defaults), schema);
}
function getTsConfigPath(tree, projectName, path) {
const { root, projectType } = (0, devkit_1.readProjectConfiguration)(tree, projectName);
return (0, path_1.join)(root, path && path.length > 0
? path
: projectType === 'application'
? 'tsconfig.app.json'
: 'tsconfig.lib.json');
}
function createProjectStorybookDir(tree, projectName, uiFramework) {
const { root, projectType } = (0, devkit_1.readProjectConfiguration)(tree, projectName);
const projectDirectory = projectType === 'application' ? 'app' : 'lib';
if (tree.exists((0, path_1.join)(root, '.storybook'))) {
return;
}
const templatePath = (0, path_1.join)(__dirname, './project-files');
const offset = (0, devkit_1.offsetFromRoot)(root);
(0, devkit_1.generateFiles)(tree, templatePath, root, {
tmpl: '',
dot: '.',
uiFramework,
offsetFromRoot: offset,
rootTsConfigPath: (0, js_1.getRootTsConfigPathInTree)(tree),
projectType: projectDirectory,
loaderDir: getProjectTsImportPath(tree, projectName),
useWebpack5: true,
});
}
function createRootStorybookDir(tree) {
if (tree.exists('.storybook')) {
return;
}
const templatePath = (0, path_1.join)(__dirname, './root-files');
(0, devkit_1.generateFiles)(tree, templatePath, '', {
tmpl: '',
dot: '.',
rootTsConfigPath: (0, js_1.getRootTsConfigPathInTree)(tree),
useWebpack5: true,
});
}
function configureTsProjectConfig(tree, schema) {
const { name: projectName } = schema;
let tsConfigPath;
let tsConfigContent;
try {
tsConfigPath = getTsConfigPath(tree, projectName);
tsConfigContent = (0, devkit_1.readJson)(tree, tsConfigPath);
}
catch (_a) {
/**
* Custom app configurations
* may contain a tsconfig.json
* instead of a tsconfig.app.json.
*/
tsConfigPath = getTsConfigPath(tree, projectName, 'tsconfig.json');
tsConfigContent = (0, devkit_1.readJson)(tree, tsConfigPath);
}
tsConfigContent.exclude = [
...(tsConfigContent.exclude || []),
'**/*.stories.ts',
'**/*.stories.js',
'**/*.stories.jsx',
'**/*.stories.tsx',
];
(0, devkit_1.writeJson)(tree, tsConfigPath, tsConfigContent);
}
function configureTsSolutionConfig(tree) {
var _a, _b;
const tsConfigPath = (0, js_1.getRootTsConfigPathInTree)(tree);
const tsConfigContent = (0, devkit_1.readJson)(tree, tsConfigPath);
if (!((_b = (_a = tsConfigContent.references) === null || _a === void 0 ? void 0 : _a.map((reference) => reference.path)) === null || _b === void 0 ? void 0 : _b.includes('./.storybook/tsconfig.json'))) {
tsConfigContent.references = [
...(tsConfigContent.references || []),
{
path: './.storybook/tsconfig.json',
},
];
}
(0, devkit_1.writeJson)(tree, tsConfigPath, tsConfigContent);
}
function addStorybookTask(tree, projectName, uiFramework) {
const projectConfig = (0, devkit_1.readProjectConfiguration)(tree, projectName);
projectConfig.targets['storybook'] = {
executor: 'nx:run-commands',
options: {
commands: [
`nx run ${projectName}:serve`,
`nx run ${projectName}:serve-storybook`,
],
parallel: true,
},
};
projectConfig.targets['serve-storybook'] = {
executor: '@nx/storybook:storybook',
options: {
uiFramework,
port: 4400,
config: {
configFolder: `${projectConfig.root}/.storybook`,
},
},
configurations: {
ci: {
quiet: true,
},
},
};
projectConfig.targets['build-storybook'] = {
executor: '@nx/storybook:build',
outputs: ['{options.outputPath}'],
options: {
uiFramework,
outputPath: (0, devkit_1.joinPathFragments)('dist/storybook', projectName),
config: {
configFolder: `${projectConfig.root}/.storybook`,
},
},
configurations: {
ci: {
quiet: true,
},
},
};
(0, devkit_1.updateProjectConfiguration)(tree, projectName, projectConfig);
}
exports.default = storybookConfigurationGenerator;
//# sourceMappingURL=generator.js.map