Skip to content

Commit

Permalink
feat: props-info hmr support
Browse files Browse the repository at this point in the history
  • Loading branch information
atanasster committed Jul 30, 2020
1 parent 85c45ac commit 51a2a53
Show file tree
Hide file tree
Showing 7 changed files with 44 additions and 25 deletions.
14 changes: 1 addition & 13 deletions core/instrument/src/babel/extract-component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import { Component, Document, PackageInfo } from '@component-controls/core';
import { hashStoreId } from '../misc/hashStore';
import { followImports } from './follow-imports';
import { packageInfo } from '../misc/package-info';
import { propsInfo } from '../misc/props-info';
import { LoadingDocStore, InstrumentOptions } from '../types';

interface ComponentParseData {
Expand Down Expand Up @@ -55,18 +54,7 @@ export const extractComponent = async (
name: componentName,
};
}
const { propsLoaders } = options || {};
if (follow && follow.filePath && Array.isArray(propsLoaders)) {
const info = await propsInfo(
propsLoaders,
follow.filePath,
follow.importedName,
follow.source,
);
if (info) {
component.info = info;
}
}

globalCache[filePath] = { component, componentPackage };
return globalCache[filePath];
};
Expand Down
1 change: 1 addition & 0 deletions core/instrument/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import {
} from './types';

export * from './types';
export { getComponentProps } from './misc/props-info';

type TraverseFn = (
ast: File,
Expand Down
2 changes: 1 addition & 1 deletion core/instrument/src/misc/props-info.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import {
} from '@component-controls/core';
import { PropsLoaderConfig } from '../types';

export const propsInfo = async (
export const getComponentProps = async (
options: PropsLoaderConfig[],
filePath: string,
componentName?: string,
Expand Down
2 changes: 1 addition & 1 deletion core/loader/src/loader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ module.exports = async function() {
if (store?.doc) {
console.log(chalk.bgRgb(244, 147, 66)('@loaded: '), filePath);
if (store.stories && store.components && store.packages) {
addStoriesDoc(filePath, context._compilation.records.hash, {
addStoriesDoc(options, filePath, context._compilation.records.hash, {
stories: store.stories,
components: store.components,
packages: store.packages,
Expand Down
19 changes: 11 additions & 8 deletions core/loader/src/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import * as path from 'path';
import * as webpack from 'webpack';
import { createHash } from 'crypto';
import jsStringEscape from 'js-string-escape';
import { store } from './store';
import { getSerializedStore } from './store';

export interface LoaderPluginOptions {
config?: string;
Expand All @@ -29,14 +29,16 @@ export class LoaderPlugin {
compiler.hooks.compilation.tap(LoaderPlugin.pluginName, compilation => {
compilation.hooks.optimizeChunkAssets.tap(
LoaderPlugin.pluginName,
chunks => {
async chunks => {
const jsFiles: string[] = [];
chunks.forEach(chunk => {
chunk.files
.filter(fileName => fileName.endsWith('.js'))
.forEach(file => {
this.replaceSource(compilation, file);
});
.forEach(fileName => jsFiles.push(fileName));
});
for (let i = 0; i < jsFiles.length; i += 1) {
await this.replaceSource(compilation, jsFiles[i]);
}
},
);
});
Expand All @@ -60,17 +62,18 @@ export class LoaderPlugin {
nmrp.apply(compiler);
}

private replaceSource(
private async replaceSource(
compilation: webpack.compilation.Compilation,
file: string,
) {
const placeholder = `__COMPILATION_HASH__${this.compilationHash}`;
const source = compilation.assets[file];
const placeholderPos = source.source().indexOf(placeholder);
if (placeholderPos > -1) {
const store = await getSerializedStore();
const newContent = this.options.escapeOutput
? jsStringEscape(JSON.stringify(store))
: JSON.stringify(store);
? jsStringEscape(store)
: store;
const newSource = new ReplaceSource(source, file);
newSource.replace(
placeholderPos,
Expand Down
29 changes: 28 additions & 1 deletion core/loader/src/store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,11 @@ import {
BuildConfiguration,
RunConfiguration,
} from '@component-controls/core';
import { LoadingDocStore } from '@component-controls/instrument';
import {
LoadingDocStore,
InstrumentOptions,
getComponentProps,
} from '@component-controls/instrument';

export interface LoadingStore {
/**
Expand Down Expand Up @@ -42,6 +46,8 @@ export const store: LoadingStore = {
buildConfig: {},
};

let instrumentOptions: InstrumentOptions = {};

export const reserveStories = (filePaths: string[]) => {
if (store.stores.length === 0) {
filePaths.forEach(filePath => store.stores.push({ filePath }));
Expand All @@ -51,10 +57,12 @@ export const removeStoriesDoc = (filePath: string) => {
store.stores = store.stores.filter(s => s.filePath !== filePath);
};
export const addStoriesDoc = (
options: InstrumentOptions,
filePath: string,
hash: string,
added: LoadingDocStore,
) => {
instrumentOptions = options;
const { components, packages, stories, doc } = added;
if (!doc) {
throw new Error(`Invalid store with no document ${filePath}`);
Expand All @@ -81,3 +89,22 @@ export const addStoriesDoc = (
store.stores.push({ filePath, hash, stories, doc });
}
};

export const getSerializedStore = async (): Promise<string> => {
const { propsLoaders = [] } = instrumentOptions;
for (const name in store.components) {
const component = store.components[name];
if (component.request) {
const propsInfo = await getComponentProps(
propsLoaders,
component.request,
component.name,
component.source,
);
if (propsInfo) {
component.info = propsInfo;
}
}
}
return JSON.stringify(store);
};
2 changes: 1 addition & 1 deletion core/store/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ export interface StoryStore {
getStore: () => Store | undefined;
getStory: (storyId: string) => Story | undefined;
getStoryDoc: (name: string) => Document | undefined;
config: RunConfiguration | undefined;
config: RunConfiguration;
store: Store;
pages: Pages;
docs: Documents;
Expand Down

0 comments on commit 51a2a53

Please sign in to comment.