Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"type": "patch",
"comment": "feat: run the story source transform before transpilation and remove the custom Babel loader",
"packageName": "@fluentui/react-storybook-addon-export-to-sandbox",
"email": "paulmardling@microsoft.com",
"dependentChangeType": "patch"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const Example = (props: { label: string }) => <button>{props.label}</button>;
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
const assert = require('node:assert');
const fs = require('node:fs');
const os = require('node:os');
const path = require('node:path');
const webpackCompiler = require('webpack');

const { webpack } = require('../../lib-commonjs/webpack.js');

async function main() {
const outputPath = fs.mkdtempSync(path.join(os.tmpdir(), 'export-to-sandbox-webpack-'));
const config = webpack(
{
mode: 'development',
devtool: 'source-map',
context: path.join(__dirname, '../fixtures'),
entry: './Example.stories.tsx',
output: { path: outputPath, filename: 'bundle.js' },
module: {
rules: [
{
test: /\.tsx?$/,
use: {
loader: require.resolve('swc-loader'),
options: {
jsc: {
parser: { syntax: 'typescript', tsx: true },
target: 'es2019',
},
},
},
},
],
},
},
{
presetsList: [
{
name: 'node_modules/@fluentui/react-storybook-addon-export-to-sandbox/lib/preset.js',
preset: {},
options: { importMappings: {} },
},
],
},
);

try {
const stats = await compile(config);
if (stats.hasErrors()) {
throw new Error(stats.toString({ all: false, errors: true, errorDetails: true }));
}

const bundle = fs.readFileSync(path.join(outputPath, 'bundle.js'), 'utf8');
assert.match(bundle, /Example\.parameters\.fullSource/);
assert.match(bundle, /label: string/);

const sourceMap = JSON.parse(fs.readFileSync(path.join(outputPath, 'bundle.js.map'), 'utf8'));
assert(sourceMap.sources.some(source => source.endsWith('Example.stories.tsx')));
assert(sourceMap.mappings.length > 0);
} finally {
fs.rmSync(outputPath, { recursive: true, force: true });
}
}

function compile(config) {
const compiler = webpackCompiler(config);

return new Promise((resolve, reject) => {
compiler.run((error, stats) => {
compiler.close(closeError => {
if (error || closeError) {
reject(error || closeError);
} else if (!stats) {
reject(new Error('Webpack compilation did not return stats.'));
} else {
resolve(stats);
}
});
});
});
}

main().catch(error => {
console.error(error);
process.exitCode = 1;
});
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,14 @@
}
]
}
},
"test-integration": {
"executor": "nx:run-commands",
"dependsOn": ["build"],
"options": {
"cwd": "{projectRoot}",
"command": "node __tests__/integration/webpack.cjs"
}
}
}
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,12 @@ describe(`webpack`, () => {

expect(actual.module?.rules).toEqual([
{
enforce: 'post',
enforce: 'pre',
test: /\.stories\.(jsx?$|tsx?$)/,
use: {
loader: expect.stringContaining('custom-babel-loader'),
loader: expect.stringContaining('babel-loader'),
options: {
parserOpts: { plugins: ['typescript', 'jsx'] },
plugins: [
[
expect.stringContaining('babel-preset-storybook-full-source'),
Expand Down Expand Up @@ -52,12 +53,13 @@ describe(`webpack`, () => {

expect(actual.module?.rules).toEqual([
{
enforce: 'post',
enforce: 'pre',
test: /\.stories\.tsx?/,
include: /foo-stories/,
use: {
loader: expect.stringContaining('custom-babel-loader'),
loader: expect.stringContaining('babel-loader'),
options: {
parserOpts: { plugins: ['typescript', 'jsx'] },
plugins: [
[
expect.stringContaining('babel-preset-storybook-full-source'),
Expand Down Expand Up @@ -90,11 +92,12 @@ describe(`webpack`, () => {

expect(actual.module?.rules).toEqual([
{
enforce: 'post',
enforce: 'pre',
test: /\.stories\.(jsx?$|tsx?$)/,
use: {
loader: expect.stringContaining('custom-babel-loader'),
loader: expect.stringContaining('babel-loader'),
options: {
parserOpts: { plugins: ['typescript', 'jsx'] },
plugins: [
[
expect.stringContaining('babel-preset-storybook-full-source'),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,17 +37,14 @@ function createBabelLoaderRule(config: Required<PresetConfig>): import('webpack'
test: /\.stories\.(jsx?$|tsx?$)/,
...webpackRule,
/**
* why the usage of 'post' ? - we need to run this loader after all storybook webpack rules/loaders have been executed.
* while we can use Array.prototype.unshift to "override" the indexes this approach is more declarative without additional hacks.
* Run before transpilers so this loader receives the original story source and does not depend on
* the format of sourcemaps emitted by subsequent loaders.
*/
enforce: 'post',
enforce: 'pre',
use: {
/**
* Custom babel loader wraps the original babel-loader and fixes the incorrect `inputSourceMap` parameter
* that is passed to babel-loader.
**/
loader: require.resolve('./custom-babel-loader'),
loader: require.resolve('babel-loader'),
options: babelLoaderOptionsUpdater({
parserOpts: { plugins: ['typescript', 'jsx'] },
plugins: [plugin],
}),
},
Expand Down
Loading