Skip to content

Commit

Permalink
feat: typescript buildtime config files
Browse files Browse the repository at this point in the history
  • Loading branch information
atanasster committed May 7, 2021
1 parent 9d2cf8a commit ad17804
Show file tree
Hide file tree
Showing 14 changed files with 133 additions and 52 deletions.
2 changes: 1 addition & 1 deletion .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@
"name": "jest config",
"program": "${workspaceFolder}/node_modules/.bin/jest",
"cwd": "${workspaceFolder}/core/config",
"args": ["config"],
"args": ["ts-build-config"],
"console": "integratedTerminal",
"internalConsoleOptions": "neverOpen",
"disableOptimisticBPs": true,
Expand Down
1 change: 0 additions & 1 deletion core/config/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@
"@component-controls/core": "^3.9.0",
"@component-controls/instrument": "^3.9.0",
"@component-controls/render": "^3.9.0",
"esm": "^3.2.25",
"glob": "^7.1.6",
"glob-base": "^0.3.0",
"micromatch": "^4.0.2",
Expand Down
6 changes: 5 additions & 1 deletion core/config/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
defaultRunConfig,
convertConfig,
} from '@component-controls/core';
import { dynamicRequire } from '@component-controls/core/node-utils';
import { render as reactRender } from '@component-controls/render/react';
import {
defaultMDXOptions,
Expand All @@ -21,8 +22,11 @@ import {

export const buildConfigFileNames = [
'buildtime.js',
'buildtime.ts',
'build.js',
'build.ts',
'main.js',
'main.ts',
'doczrc.js',
];

Expand Down Expand Up @@ -75,7 +79,7 @@ export const loadConfig = (
);
if (buildConfigFile) {
const buildPath = path.resolve(configPath, buildConfigFile);
let config = require('esm')(module)(buildPath);
let config = dynamicRequire(buildPath);
if (
!config ||
(typeof config === 'object' && Object.keys(config).length === 0)
Expand Down
11 changes: 11 additions & 0 deletions core/config/test/fixtures/ts-config/buildtime.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { BuildConfiguration } from '@component-controls/core';
const config: BuildConfiguration = {
stories: ['../*.docs.tsx'],
instrument: {
components: {
tests: true,
},
},
};

export default config;
18 changes: 18 additions & 0 deletions core/config/test/ts-build-config.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import path from 'path';
import { loadConfiguration } from '../src/index';

describe('ts-build-config', () => {
it('typescript building config', () => {
const config = loadConfiguration(
path.resolve(__dirname, './fixtures', 'ts-config'),
);
expect(config.config).toMatchObject({
stories: ['../*.docs.tsx'],
instrument: {
components: {
tests: true,
},
},
});
});
});
1 change: 1 addition & 0 deletions core/core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
"esm": "^3.2.25",
"faker": "^4.1.0",
"path": "^0.12.7",
"tmp": "^0.2.1",
"typescript": "^4.0.5"
},
"devDependencies": {
Expand Down
25 changes: 25 additions & 0 deletions core/core/src/controls-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -366,6 +366,30 @@ export const transformControls = (
: undefined;
};

const typeNames: Record<string, ControlTypes> = {
'ControlTypes.TEXT': ControlTypes.TEXT,
'ControlTypes.NUMBER': ControlTypes.NUMBER,
'ControlTypes.BOOLEAN': ControlTypes.BOOLEAN,
'ControlTypes.OPTIONS': ControlTypes.OPTIONS,
'ControlTypes.DATE': ControlTypes.DATE,
'ControlTypes.COLOR': ControlTypes.COLOR,
'ControlTypes.BUTTON': ControlTypes.BUTTON,
'ControlTypes.OBJECT': ControlTypes.OBJECT,
'ControlTypes.ARRAY': ControlTypes.ARRAY,
'ControlTypes.FILES': ControlTypes.FILES,
};
export const fixControlTypes = (
controls: ComponentControls,
): ComponentControls => {
return Object.keys(controls).reduce((acc, key) => {
const control = controls[key];
if (typeof control === 'object' && control.type) {
const newType = typeNames[control.type] || control.type;
return { ...acc, [key]: { ...control, type: newType } };
}
return { ...acc, [key]: control };
}, {});
};
/**
* create controls for a story
* @param story - the story for which to create controls. Will check if the story accepts any arguments
Expand All @@ -379,6 +403,7 @@ export const getStoryControls = (
components: Components,
): ComponentControls | undefined => {
const { controls: storyControls } = story;

if (!story.arguments?.length) {
//story has no arguments
return transformControls(storyControls);
Expand Down
65 changes: 48 additions & 17 deletions core/core/src/modules.ts
Original file line number Diff line number Diff line change
@@ -1,33 +1,64 @@
import path from 'path';
import fs from 'fs';
import * as ts from 'typescript';
import { dirSync } from 'tmp';
import { deepMerge } from './deepMerge';

/**
* returns the basename stripped of the extension
* @param filePath full file path
*/
export const nakedFileName = (filePath: string): string => {
const baseName = path.basename(filePath);
return baseName.substr(0, baseName.lastIndexOf('.'));
};

export const dynamicRequire = (filePath: string): any => {
const fileParts = filePath.split('.');
const ext = fileParts.pop()?.toLowerCase() || 'js';
const ext =
filePath
.split('.')
.pop()
?.toLowerCase() || 'js';
if (['ts', 'tsx'].indexOf(ext) !== -1) {
const config: ReturnType<typeof ts.readConfigFile> = {
config: {
compilerOptions: {
jsx: ts.JsxEmit.ReactJSX,
module: ts.ModuleKind.ES2015,
},
},
};
const configPath = ts.findConfigFile(
path.dirname(filePath),
ts.sys.fileExists,
);
const config = configPath
? ts.readConfigFile(configPath, ts.sys.readFile)
: {
config: {
compilerOptions: {
allowJs: true,
jsx: ts.JsxEmit.ReactJSX,
module: ts.ModuleKind.CommonJS,
},
},
};
if (configPath) {
config.config = deepMerge(
config.config,
ts.readConfigFile(configPath, ts.sys.readFile).config,
);
}

const program = ts.createProgram([filePath], config.config);
program.emit();
const jsFilePath = `${fileParts.join('.')}.js`;
const tmpDir = dirSync();
config.config.compilerOptions.outDir = tmpDir.name;
try {
const program = ts.createProgram(
[filePath],
config.config.compilerOptions,
);
const nakedFile = nakedFileName(filePath);
// by default output file name same but with .js extension
let jsFilePath = path.resolve(tmpDir.name, nakedFile + '.js');
program.emit(undefined, (fileName: string, data: string) => {
if (nakedFileName(fileName) === nakedFile) {
jsFilePath = fileName;
}
ts.sys.writeFile(fileName, data);
});
return require('esm')(module)(jsFilePath);
} finally {
//fs.unlinkSync(tmpFilePath);
fs.rmdirSync(tmpDir.name, { recursive: true });
// tmpDir.removeCallback();
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
const path = require('path');
import path from 'path';
import { BuildConfiguration } from '@component-controls/core';
require('dotenv').config();
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer')
.BundleAnalyzerPlugin;
//const BundleAnalyzerPlugin = require('webpack-bundle-analyzer')
// .BundleAnalyzerPlugin;

module.exports = {
const config: BuildConfiguration = {
stories: [
'../../stories/src/blogs/*.mdx',
'../../stories/src/showcase/*.mdx',
Expand Down Expand Up @@ -108,3 +109,5 @@ module.exports = {
},
},
};

export default config;
3 changes: 2 additions & 1 deletion plugins/cc-cli/src/cli/save-data-template.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import path from 'path';
import fs from 'fs';
import { dynamicRequire } from '@component-controls/core/node-utils';
import { CliOptions, getTestFolder } from './utils';
import { TemplateOptions, DataImportOptions, relativeImport } from '../utils';
import { createDataTemplate } from '../data-templates/data-template';
Expand All @@ -26,7 +27,7 @@ export const saveDataTemplate = async <P extends TemplateOptions>(
if (overwrite) {
//load existing data file

existing = require('esm')(module)(filePath);
existing = dynamicRequire(filePath);
if (
!existing ||
(typeof existing === 'object' && Object.keys(existing).length === 0)
Expand Down
12 changes: 9 additions & 3 deletions plugins/cc-cli/src/data-templates/data-template.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
import dot from 'dot';
import { getStoryControls, randomizeData } from '@component-controls/core';
import {
getStoryControls,
randomizeData,
fixControlTypes,
} from '@component-controls/core';
import { prettify } from '@component-controls/instrument';
import { StoryTemplateOptions } from '../utils';
import { getStore } from '../store';
Expand Down Expand Up @@ -35,8 +39,10 @@ export const createDataTemplate = async (
const data: Record<string, any> = {};
Object.keys(stories).forEach(storyId => {
const story = stories[storyId];
const controls = getStoryControls(story, doc, components);
if (controls) {

const storyControls = getStoryControls(story, doc, components);
if (storyControls) {
const controls = fixControlTypes(storyControls);
const values: Record<string, any> = existing?.[storyId] || {};
for (let i = Object.keys(values).length; i < numValues; i += 1) {
const rnd = randomizeData(controls);
Expand Down
22 changes: 2 additions & 20 deletions plugins/cc-cli/src/store.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,4 @@
import {
Components,
Document,
Stories,
assignProps,
} from '@component-controls/core';
import { dynamicRequire } from '@component-controls/core/node-utils';
import { Components, Document, Stories } from '@component-controls/core';
import { parseStories } from '@component-controls/instrument';
import { loadStore } from '@component-controls/store';

Expand Down Expand Up @@ -75,19 +69,7 @@ export const getStore = async ({
if (doc.isMDXComponent || !Object.keys(stories).length) {
return undefined;
}
try {
const loaded = dynamicRequire(storyPath);
if (loaded.default) {
assignProps(doc, loaded.default);
}
Object.keys(stories).forEach(storyId => {
if (loaded[storyId]) {
assignProps(stories[storyId], loaded[storyId]);
}
});
} catch (e) {
console.error(e);
}

cache.storyPath[storyPath] = {
doc,
stories,
Expand Down
2 changes: 1 addition & 1 deletion plugins/cc-cli/test/run-cli-tests.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import path from 'path';
import fs from 'fs';
import mockArgv from 'mock-argv';
const mockArgv = require('mock-argv');

import { run } from '../src/cli/cli';

Expand Down
6 changes: 3 additions & 3 deletions tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
"strictPropertyInitialization": true,
"noImplicitThis": true,
"alwaysStrict": false,
"noImplicitUseStrict": true,
"noImplicitUseStrict": true,
"noUnusedLocals": true,
"noUnusedParameters": false,
"noImplicitReturns": true,
Expand All @@ -26,5 +26,5 @@
"pretty": true,
"lib": ["es2017", "dom"]
},
"include": ["doc/**/*"],
}
"include": ["doc/**/*"]
}

0 comments on commit ad17804

Please sign in to comment.