Skip to content

Commit

Permalink
Merge pull request #415 from 10up/fix/support-ts-imports-in-block-json
Browse files Browse the repository at this point in the history
Fix: transform file extension for `.ts` and `.tsx` assets inside `block.json` files
  • Loading branch information
fabiankaegy authored Sep 24, 2024
2 parents cb646bb + 95aeb0f commit 75b890b
Show file tree
Hide file tree
Showing 5 changed files with 129 additions and 38 deletions.
5 changes: 5 additions & 0 deletions .changeset/young-guests-deliver.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"10up-toolkit": patch
---

Fix: transform file extension for .ts and .tsx assets inside block.json files
4 changes: 2 additions & 2 deletions packages/toolkit/config/webpack/plugins.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ const {
fromConfigRoot,
hasProjectFile,
getArgFromCLI,
maybeInsertStyleVersionHash,
transformBlockJson,
} = require('../../utils');
const { isPackageInstalled } = require('../../utils/package');

Expand Down Expand Up @@ -164,7 +164,7 @@ module.exports = ({
noErrorOnMissing: true,
to: 'blocks/[path][name][ext]',
transform: (content, absoluteFilename) => {
return maybeInsertStyleVersionHash(content, absoluteFilename);
return transformBlockJson(content, absoluteFilename);
},
},
useBlockAssets && {
Expand Down
83 changes: 69 additions & 14 deletions packages/toolkit/utils/__tests__/blocks.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import path from 'path';
import { maybeInsertStyleVersionHash } from '../blocks';
import { transformBlockJson } from '../blocks';
import { getFileContentHash as getFileContentHashMock } from '../file';

jest.mock('../file', () => {
Expand All @@ -10,61 +10,65 @@ jest.mock('../file', () => {
return module;
});

describe('maybeInsertStyleVersionHash', () => {
describe('transformBlockJson', () => {
const absoluteteFileName = path.join('dist', 'blocks', 'block.json');

it('does nothing if version is set', () => {
expect(
maybeInsertStyleVersionHash(
transformBlockJson(
JSON.stringify({
version: 1,
style: 'file:./style.css',
}),
absoluteteFileName,
),
).toEqual(JSON.stringify({ version: 1, style: 'file:./style.css' }));
).toEqual(JSON.stringify({ version: 1, style: 'file:./style.css' }, null, 2));
});

it('does nothing if style is not set', () => {
expect(
maybeInsertStyleVersionHash(
transformBlockJson(
JSON.stringify({
script: 'file:./script.js',
}),
absoluteteFileName,
),
).toEqual(
JSON.stringify({
script: 'file:./script.js',
}),
JSON.stringify(
{
script: 'file:./script.js',
},
null,
2,
),
);
});

it('does nothing if style does not start with file:', () => {
expect(
maybeInsertStyleVersionHash(
transformBlockJson(
JSON.stringify({
style: 'style.css',
}),
absoluteteFileName,
),
).toEqual(JSON.stringify({ style: 'style.css' }));
).toEqual(JSON.stringify({ style: 'style.css' }, null, 2));

expect(
maybeInsertStyleVersionHash(
transformBlockJson(
JSON.stringify({
style: ['another-css', 'style.css'],
}),
absoluteteFileName,
),
).toEqual(JSON.stringify({ style: ['another-css', 'style.css'] }));
).toEqual(JSON.stringify({ style: ['another-css', 'style.css'] }, null, 2));
});

it('adds version if style are set but version is not', () => {
getFileContentHashMock.mockReturnValue('12345678');

expect(
maybeInsertStyleVersionHash(
transformBlockJson(
JSON.stringify({
style: 'file:./style.css',
}),
Expand All @@ -86,7 +90,7 @@ describe('maybeInsertStyleVersionHash', () => {
);

expect(
maybeInsertStyleVersionHash(
transformBlockJson(
JSON.stringify({
style: ['another-style', 'file:./style2.css'],
}),
Expand All @@ -107,4 +111,55 @@ describe('maybeInsertStyleVersionHash', () => {
path.join('dist', 'blocks', 'style2.css'),
);
});

it('transforms ts and tsx to js', () => {
expect(
transformBlockJson(
JSON.stringify({
script: 'file:./script.ts',
editorScript: 'file:./editor.tsx',
viewScript: 'file:./view.ts',
viewScriptModule: 'file:./view.tsx',
scriptModule: 'file:./script.tsx',
}),
absoluteteFileName,
),
).toEqual(
JSON.stringify(
{
script: 'file:./script.js',
editorScript: 'file:./editor.js',
viewScript: 'file:./view.js',
viewScriptModule: 'file:./view.js',
scriptModule: 'file:./script.js',
},
null,
2,
),
);
expect(
transformBlockJson(
JSON.stringify({
script: ['file:./script.ts', 'file:./script.tsx'],
editorScript: ['file:./editor.ts', 'file:./editor.tsx'],
viewScript: ['file:./view.ts', 'file:./view.tsx'],
viewScriptModule: ['file:./view.tsx', 'file:./view.ts'],
scriptModule: ['file:./script.ts', 'file:./script.tsx'],
}),
absoluteteFileName,
),
).toEqual(
JSON.stringify(
{
script: ['file:./script.js', 'file:./script.js'],
editorScript: ['file:./editor.js', 'file:./editor.js'],
viewScript: ['file:./view.js', 'file:./view.js'],
viewScriptModule: ['file:./view.js', 'file:./view.js'],
scriptModule: ['file:./script.js', 'file:./script.js'],
},
null,
2,
),
);
});
});
71 changes: 51 additions & 20 deletions packages/toolkit/utils/blocks.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,33 @@
const path = require('path');
const { getFileContentHash } = require('./file');

const maybeInsertStyleVersionHash = (content, absoluteFilename) => {
const JS_ASSET_KEYS = ['script', 'editorScript', 'viewScript', 'viewScriptModule', 'scriptModule'];

/**
* Transform the asset path from `.ts or .tsx` to `.js`
*
* When a block.json file has a script or style property that points to a `.ts or .tsx` file,
* this function will transform the path to point to the `.js` file instead.
*
* @param {string|Array<string>} asset - The asset path to transform
* @returns {string|Array<string>}
*/
function transformTSAsset(asset) {
function replaceExtension(filePath) {
const isFilePath = filePath.startsWith('file:');
if (!isFilePath) {
return filePath;
}

// replace the `.ts or .tsx` extension with `.js`
const jsPath = filePath.replace(/\.tsx?$/, '.js');
return jsPath;
}

return Array.isArray(asset) ? asset.map(replaceExtension) : replaceExtension(asset);
}

const transformBlockJson = (content, absoluteFilename) => {
const rawMetadata = content.toString();
if (rawMetadata === '') {
return content;
Expand All @@ -15,31 +41,36 @@ const maybeInsertStyleVersionHash = (content, absoluteFilename) => {
const isFilePath = styleArray?.some((styleName) => styleName?.startsWith('file:'));
const hasVersion = version !== undefined;

if (hasVersion || !isFilePath) {
return content;
}

const absoluteDirectory = absoluteFilename.replace(/block\.json$/, '');

let styleFileContentHash = '';

styleArray.forEach((rawStylePath) => {
if (!rawStylePath.startsWith('file:')) {
return;
if (!hasVersion && isFilePath) {
styleArray.forEach((rawStylePath) => {
if (!rawStylePath.startsWith('file:')) {
return;
}
const stylePath = rawStylePath.replace('file:', '');
const absoluteStylePath = path.join(absoluteDirectory, stylePath);
styleFileContentHash += getFileContentHash(absoluteStylePath);
});
}

const newMetadata = {
...metadata,
};

if (!hasVersion && styleFileContentHash) {
newMetadata.version = styleFileContentHash;
}

JS_ASSET_KEYS.forEach((key) => {
if (metadata[key]) {
newMetadata[key] = transformTSAsset(metadata[key]);
}
const stylePath = rawStylePath.replace('file:', '');
const absoluteStylePath = path.join(absoluteDirectory, stylePath);
styleFileContentHash += getFileContentHash(absoluteStylePath);
});

return JSON.stringify(
{
...metadata,
version: styleFileContentHash,
},
null,
2,
);
return JSON.stringify(newMetadata, null, 2);
};

module.exports = { maybeInsertStyleVersionHash };
module.exports = { transformBlockJson };
4 changes: 2 additions & 2 deletions packages/toolkit/utils/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ const { hasPackageProp, getPackagePath, getPackage, getPackageVersion } = requir

const { displayWebpackStats } = require('./webpack');

const { maybeInsertStyleVersionHash } = require('./blocks');
const { transformBlockJson } = require('./blocks');

const {
getProjectRoot,
Expand Down Expand Up @@ -79,6 +79,6 @@ module.exports = {
getTenUpScriptsPackageBuildConfig,
hasWebpackConfig,
displayWebpackStats,
transformBlockJson,
getGitBranch,
maybeInsertStyleVersionHash,
};

0 comments on commit 75b890b

Please sign in to comment.