Skip to content

Commit

Permalink
feat: add preconfig transform
Browse files Browse the repository at this point in the history
  • Loading branch information
nvh95 committed Apr 14, 2022
1 parent 5291ef3 commit 6ce35ca
Show file tree
Hide file tree
Showing 8 changed files with 101 additions and 4 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,5 @@ dist-ssr
.npmrc

build
presets
transforms
76 changes: 76 additions & 0 deletions cssTransform.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
'use strict';

Object.defineProperty(exports, '__esModule', { value: true });

require('path');
require('camelcase');

function getRelativeFilename(filename) {
return filename.split(process.cwd())[1];
}
function processCss(src, filename) {
if (filename.endsWith('.module.css')) {
return processCSSModules(src, filename);
}
const relativeFilename = getRelativeFilename(filename);
// Transform to a javascript module that load a <link rel="stylesheet"> tag to the page.
return `const relativeCssPath = "${relativeFilename}";
const link = document.createElement('link');
link.rel = 'stylesheet';
link.href = relativeCssPath;
document.body.appendChild(link);
module.exports = JSON.stringify(relativeCssPath);`;
}
// TODO: MEDIUM PRIORITY To research about getCacheKey
// Reference:
// - https://jestjs.io/docs/code-transformation#writing-custom-transformers
// - https://github.com/swc-project/jest/blob/17cf883b46c050a485975d8ce96a05277cf6032f/index.ts#L37-L52
// const cacheKeyFunction = createCacheKey();
// export function getCacheKey(src: string, filename: string, ...rest): string {
// const baseCacheKey = cacheKeyFunction(src, filename, ...rest);
// return crypto.createHash('md5').update(baseCacheKey).digest('hex');
// }
// We cannot create async transformer if we are using CommonJS
// ( Reference: https://github.com/facebook/jest/issues/11081#issuecomment-791259034
// https://github.com/facebook/jest/issues/11458
// Also, there is a inconsistency in jest docs about should `process` be required
// https://jestjs.io/docs/configuration#transform-objectstring-pathtotransformer--pathtotransformer-object
// A transformer must be an object with at least a process function
// https://jestjs.io/docs/code-transformation#writing-custom-transformers
// As can be seen, only process or processAsync is mandatory to implement)
// We can use that if we opt-in to ESM. But it's not common use case right now (2022)
// So our approach is making CSS Modules a "CSS-in-JS" solution.
// CSS Modules will be compiled at run time then inject to the document.body
// One notable note is that `postcss-modules` is an async postcss plugin
// so we need to use `postcss-modules.sync`, with function `sync()`
function processCSSModules(src, filename) {
return `
const postcss = require('postcss');
const CSSModulesSync = require('postcss-modules-sync').default;
const cssSrc = ${JSON.stringify(src)};
let exportedTokens = {};
const result = postcss(
CSSModulesSync({
getJSON: (tokens) => {
exportedTokens = tokens;
},
}),
)
.process(cssSrc, { from: ${JSON.stringify(filename)} })
const style = document.createElement('style');
style.type = 'text/css';
style.appendChild(document.createTextNode(result.css));
document.body.appendChild(style);
module.exports = exportedTokens`;
}

function process$1(src, filename) {
return processCss(src, filename);
}

exports.process = process$1;
4 changes: 2 additions & 2 deletions examples/vite-react/jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ module.exports = {
modulePaths: ['<rootDir>/src'],
transform: {
'^.+\\.(ts|js|tsx|jsx)$': '@swc/jest',
'^.+\\.css$': '<rootDir>/config/jest/cssTransform.js',
'^.+\\.css$': 'jest-preview/transforms/css',
'^(?!.*\\.(js|jsx|mjs|cjs|ts|tsx|css|json)$)':
'<rootDir>/config/jest/fileTransform.js',
'jest-preview/transforms/file',
},
transformIgnorePatterns: [
'[/\\\\]node_modules[/\\\\].+\\.(js|jsx|mjs|cjs|ts|tsx)$',
Expand Down
1 change: 1 addition & 0 deletions examples/vite-react/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
"preview": "vite preview",
"jest-preview": "jest-preview",
"test": "NODE_ENV=test jest --watch",
"test:nc": "npm run test -- --no-cache",
"test:debug": "npm-run-all -p test jest-preview"
},
"dependencies": {
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@
},
"files": [
"dist",
"server"
"server",
"transforms"
],
"scripts": {
"dev": "vite",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import { processCss } from '../transform';

export function process(src: string, filename: string) {
function process(src: string, filename: string) {
return processCss(src, filename);
}
export default { process };
8 changes: 8 additions & 0 deletions src/preconfigTransform/file.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
'use strict';

import { processFile } from '../transform';

function process(src: string, filename: string) {
return processFile(src, filename);
}
export default { process };
8 changes: 8 additions & 0 deletions src/preconfigTransform/fileCRA.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
'use strict';

import { processFileCRA } from '../transform';

function process(src: string, filename: string) {
return processFileCRA(src, filename);
}
export default { process };

0 comments on commit 6ce35ca

Please sign in to comment.