Skip to content

Commit

Permalink
feat: refactor webpck loader to pitch
Browse files Browse the repository at this point in the history
  • Loading branch information
atanasster committed Apr 20, 2020
1 parent 2ea190e commit 839ae3e
Show file tree
Hide file tree
Showing 28 changed files with 35,731 additions and 116 deletions.
15 changes: 15 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,21 @@
"<node_internals>/**"
]
},
{
"type": "node",
"request": "launch",
"name": "storybook-6-build",
"runtimeExecutable": "npm",
"cwd": "${workspaceFolder}/examples/storybook-6",
"runtimeArgs": [
"run-script",
"debug-build"
],
"port": 9229,
"skipFiles": [
"<node_internals>/**"
]
},
{
"type": "node",
"request": "launch",
Expand Down
1 change: 0 additions & 1 deletion core/instrument/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,6 @@ export const parseStories = async (
const exportsSource = extractStoryExports(exports);
let transformed = source;
if (transformMDX && exportsSource) {
debugger;
transformed = `${renderer}\n${code}\n${exportsSource}`;
}
return {
Expand Down
5 changes: 1 addition & 4 deletions core/loader/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,9 @@
"@component-controls/instrument": "^0.6.0",
"@component-controls/specification": "^0.6.0",
"@storybook/csf": "^0.0.1",
"crypto": "^1.0.1",
"js-string-escape": "^1.0.1",
"loader-utils": "^1.2.3",
"typescript": "^3.8.3",
"webpack": "^4.41.6",
"webpack-sources": "^1.4.3"
"webpack": "^4.41.6"
},
"devDependencies": {
"@types/jest": "^25.1.2",
Expand Down
30 changes: 13 additions & 17 deletions core/loader/src/loader.ts
Original file line number Diff line number Diff line change
@@ -1,31 +1,27 @@
import * as fs from 'fs';
import * as path from 'path';
import { getOptions } from 'loader-utils';
import { loader } from 'webpack';
import {
InstrumentOptions,
parseStories,
} from '@component-controls/instrument';
import { StoriesStore } from '@component-controls/specification';

import { addStoriesKind } from './store';

module.exports.default = async function(source: string) {
module.exports.pitch = async function(
remRequest: string,
precRequest: string,
data: any,
) {
const options: InstrumentOptions = getOptions(this) || {};
const callback = this.async();
const context = this as loader.LoaderContext;
const filePath = context.resourcePath;
let transformed: string;
let store: StoriesStore;
try {
({ transformed, ...store } = await parseStories(source, filePath, options));
} catch (err) {
return callback(err);
}
const filePath = this.resource;
const source = fs.readFileSync(filePath, 'utf8');
const { transformed, ...store } = await parseStories(source, filePath, options);
if (store) {
const relPath = path.relative(context.rootContext, context.resourcePath);
const relPath = path.relative(context.rootContext, filePath);
const moduleId = relPath.startsWith('.') ? relPath : `./${relPath}`;
// const time = new Date();
const fileName = path.join(__dirname, 'story-store-data.js');
// fs.utimesSync(fileName, time, time);
addStoriesKind({
stories: store.stories,
components: store.components,
Expand All @@ -34,13 +30,13 @@ module.exports.default = async function(source: string) {
...acc,
[key]: {
...store.kinds[key],
fileName,
fileName: filePath,
moduleId: moduleId,
},
}),
{},
),
});
}
return callback(null, transformed);
return transformed;
};
53 changes: 1 addition & 52 deletions core/loader/src/plugin.ts
Original file line number Diff line number Diff line change
@@ -1,39 +1,10 @@
import { ReplaceSource } from 'webpack-sources';
import jsStringEscape from 'js-string-escape';
import * as path from 'path';
import * as webpack from 'webpack';
import { createHash } from 'crypto';
import { store } from './store';

class StoriesInjectPlugin {
public static pluginName = 'stories-inject-plugin';
private readonly compilationHash: string;
constructor() {
const hash = createHash('md5')
.update(new Date().getTime().toString())
.digest('hex');
this.compilationHash = `__${hash.substr(0, 6)}__`;
}

apply(compiler: webpack.Compiler) {
this.replaceRuntimeModule(compiler);
compiler.hooks.compilation.tap(
StoriesInjectPlugin.pluginName,
compilation => {
compilation.hooks.optimizeChunkAssets.tap(
StoriesInjectPlugin.pluginName,
chunks => {
chunks.forEach(chunk => {
chunk.files
.filter(fileName => fileName.endsWith('.js'))
.forEach(file => {
this.replaceSource(compilation, file);
});
});
},
);
},
);
}

private replaceRuntimeModule(compiler: any) {
Expand All @@ -43,34 +14,12 @@ class StoriesInjectPlugin {
if (resource.resource) {
resource.loaders.push({
loader: path.join(__dirname, 'runtimeLoader.js'),
options: JSON.stringify({ compilationHash: this.compilationHash }),
});
}
},
);
nmrp.apply(compiler);
}

private replaceSource(
compilation: webpack.compilation.Compilation,
file: string,
) {
const placeholder = `${this.compilationHash}INJECTED_STORIES__`;
const source = compilation.assets[file];
const placeholderPos = source.source().indexOf(placeholder);
if (placeholderPos > -1) {
store.hash = this.compilationHash;
const newContent = jsStringEscape(JSON.stringify(store));
const source = compilation.assets[file];
const newSource = new ReplaceSource(source, file);
newSource.replace(
placeholderPos,
placeholderPos + placeholder.length - 1,
newContent,
);
compilation.assets[file] = newSource;
}
}
}
}

module.exports = StoriesInjectPlugin;
20 changes: 4 additions & 16 deletions core/loader/src/runtimeLoader.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,6 @@
/* eslint-disable mdx/no-unused-expressions */
import { createHash } from 'crypto';
import { store } from './store';

module.exports = function(content: string) {
//@ts-ignore
this.cacheable && this.cacheable();
//@ts-ignore
const params = JSON.parse(this.query.slice(1));
content = content.replace(/__STORIES_HASH__/g, params.compilationHash);
const hash = createHash('md5')
.update(new Date().getTime().toString())
.digest('hex');

return `
module.exports.hash = "${hash}";
${content}
`;
module.exports = function() {
const newContent = `export default ${JSON.stringify(store)};`;
return newContent;
};
1 change: 0 additions & 1 deletion core/loader/src/store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ export const store: {
/**
* unique has for a store
*/
hash?: string;
stores: StoriesStore[];
} = {
stores: [],
Expand Down
7 changes: 1 addition & 6 deletions core/loader/src/story-store-data.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1 @@
const injectedStories = '__STORIES_HASH__INJECTED_STORIES__';

const getInjectedStore = (): string | undefined =>
injectedStories.startsWith('__') ? undefined : injectedStories;

export default getInjectedStore;
export default null;
4 changes: 0 additions & 4 deletions core/specification/src/stories.ts
Original file line number Diff line number Diff line change
Expand Up @@ -250,10 +250,6 @@ export interface StoryStories {
* store of stories information in memory after the loader is applied
*/
export interface StoriesStore {
/**
* unique hash for a store
*/
hash?: string;
/**
* list of story files, or groups
*/
Expand Down
10 changes: 3 additions & 7 deletions core/store/src/serialization/load-store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import { StoriesStore, Story } from '@component-controls/specification';
const deepMerge = require('deepmerge');
import { toId, storyNameFromExport } from '@storybook/csf';
import getInjectedStore from '@component-controls/loader/story-store-data';
import store from '@component-controls/loader/story-store-data';
import { addSmartControls } from './smart-controls';

let storyStore: StoriesStore | undefined = undefined;
Expand All @@ -12,26 +12,22 @@ export const loadStoryStore = (): StoriesStore | undefined => {
if (storyStore) {
return storyStore;
}
const injectedStories = getInjectedStore();
if (injectedStories) {
if (store) {
try {
const {
stores,
hash,
}: { stores: StoriesStore[]; hash: string } = JSON.parse(injectedStories);
}: { stores: StoriesStore[] } = store;

if (stores) {
const globalStore: StoriesStore = {
kinds: {},
hash,
stories: {},
components: {},
};
stores.forEach(store => {
if (Object.keys(store.kinds).length > 0) {
Object.keys(store.kinds).forEach(kindName => {
const kind = store.kinds[kindName];

if (kind.moduleId && __webpack_require__) {
try {
// './src/stories/smart-prop-type.stories.js'
Expand Down
2 changes: 1 addition & 1 deletion docs/iframe.html
Original file line number Diff line number Diff line change
Expand Up @@ -71,4 +71,4 @@
}</script><style>#root[hidden],
#docs-root[hidden] {
display: none !important;
}</style></head><body><div class="sb-nopreview sb-wrapper"><div class="sb-nopreview_main"><h1 class="sb-nopreview_heading sb-heading">No Preview</h1><p>Sorry, but you either have no stories or none are selected somehow.</p><ul><li>Please check the Storybook config.</li><li>Try reloading the page.</li></ul><p>If the problem persists, check the browser console, or the terminal you've run Storybook from.</p></div></div><div class="sb-errordisplay sb-wrapper"><pre id="error-message" class="sb-heading"></pre><pre class="sb-errordisplay_code"><code id="error-stack"></code></pre></div><div id="root"></div><div id="docs-root"></div><script src="./sb_dll/storybook_docs_dll.js"></script><script src="runtime~main.022f32cf14006b2595e9.bundle.js"></script><script src="vendors~main.022f32cf14006b2595e9.bundle.js"></script><script src="main.022f32cf14006b2595e9.bundle.js"></script></body></html>
}</style></head><body><div class="sb-nopreview sb-wrapper"><div class="sb-nopreview_main"><h1 class="sb-nopreview_heading sb-heading">No Preview</h1><p>Sorry, but you either have no stories or none are selected somehow.</p><ul><li>Please check the Storybook config.</li><li>Try reloading the page.</li></ul><p>If the problem persists, check the browser console, or the terminal you've run Storybook from.</p></div></div><div class="sb-errordisplay sb-wrapper"><pre id="error-message" class="sb-heading"></pre><pre class="sb-errordisplay_code"><code id="error-stack"></code></pre></div><div id="root"></div><div id="docs-root"></div><script src="./sb_dll/storybook_docs_dll.js"></script><script src="runtime~main.0c8fe433eea1605672a2.bundle.js"></script><script src="vendors~main.0c8fe433eea1605672a2.bundle.js"></script><script src="main.0c8fe433eea1605672a2.bundle.js"></script></body></html>
2 changes: 1 addition & 1 deletion docs/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,4 @@
}</script><style>#root[hidden],
#docs-root[hidden] {
display: none !important;
}</style></head><body><div id="root"></div><div id="docs-root"></div><script>window['DOCS_MODE'] = false;</script><script src="runtime~main.ab7db0239d02e2e25577.bundle.js"></script><script src="vendors~main.0471631db9c996a5be2d.bundle.js"></script><script src="main.960b291f16add2c8672b.bundle.js"></script></body></html>
}</style></head><body><div id="root"></div><div id="docs-root"></div><script>window['DOCS_MODE'] = false;</script><script src="runtime~main.ab7db0239d02e2e25577.bundle.js"></script><script src="vendors~main.0471631db9c996a5be2d.bundle.js"></script><script src="main.ac547c9cae810c93df3f.bundle.js"></script></body></html>
2 changes: 0 additions & 2 deletions docs/main.022f32cf14006b2595e9.bundle.js

This file was deleted.

2 changes: 2 additions & 0 deletions docs/main.0c8fe433eea1605672a2.bundle.js

Large diffs are not rendered by default.

Loading

0 comments on commit 839ae3e

Please sign in to comment.