Skip to content

Commit

Permalink
feat(rollup): former @linaria/rollup (#9)
Browse files Browse the repository at this point in the history
  • Loading branch information
Anber authored Oct 5, 2023
1 parent 170fe1c commit 6f8ae08
Show file tree
Hide file tree
Showing 12 changed files with 316 additions and 2 deletions.
7 changes: 7 additions & 0 deletions .changeset/famous-radios-doubt.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
'@wyw-in-js/transform': patch
'@wyw-in-js/rollup': patch
'wyw-in-js': patch
---

Plugin for Rollup.
3 changes: 3 additions & 0 deletions packages/rollup/.eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module.exports = {
extends: ['@wyw-in-js/eslint-config/library'],
};
3 changes: 3 additions & 0 deletions packages/rollup/babel.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
const config = require('@wyw-in-js/babel-config');

module.exports = config;
18 changes: 18 additions & 0 deletions packages/rollup/jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// @ts-check

/**
* @type {import('@jest/types').Config.InitialOptions}
*/
module.exports = {
displayName: 'webpack-loader',
preset: '@wyw-in-js/jest-preset',
transform: {
'^.+\\.ts$': [
'ts-jest',
{
tsconfig: '<rootDir>/tsconfig.spec.json',
isolatedModules: true,
},
],
},
};
47 changes: 47 additions & 0 deletions packages/rollup/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
{
"name": "@wyw-in-js/rollup",
"version": "0.1.0",
"dependencies": {
"@wyw-in-js/shared": "workspace:*",
"@wyw-in-js/transform": "workspace:*",
"@rollup/pluginutils": "^5.0.4"
},
"devDependencies": {
"@types/node": "^16.18.55",
"@wyw-in-js/babel-config": "workspace:*",
"@wyw-in-js/eslint-config": "workspace:*",
"@wyw-in-js/jest-preset": "workspace:*",
"@wyw-in-js/ts-config": "workspace:*",
"rollup": "^3.11.0",
"source-map": "^0.7.4"
},
"engines": {
"node": ">=16.0.0"
},
"files": [
"esm/",
"lib/",
"types/"
],
"license": "MIT",
"exports": {
"import": "./esm/index.js",
"require": "./lib/index.js",
"types": "./types/index.d.ts"
},
"main": "lib/index.js",
"module": "esm/index.js",
"peerDependencies": {
"rollup": "1.20.0||^2.0.0||^3.0.0"
},
"publishConfig": {
"access": "public"
},
"scripts": {
"build:esm": "babel src --out-dir esm --extensions '.js,.jsx,.ts,.tsx' --source-maps --delete-dir-on-start",
"build:lib": "cross-env NODE_ENV=legacy babel src --out-dir lib --extensions '.js,.jsx,.ts,.tsx' --source-maps --delete-dir-on-start",
"build:types": "tsc --project ./tsconfig.lib.json --baseUrl . --rootDir ./src",
"lint": "eslint --ext .js,.ts ."
},
"types": "types/index.d.ts"
}
145 changes: 145 additions & 0 deletions packages/rollup/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
/**
* This file contains a Rollup loader for wyw-in-js.
* It uses the transform.ts function to generate class names from source code,
* returns transformed code without template literals and attaches generated source maps
*/

import { createFilter } from '@rollup/pluginutils';
import type { Plugin } from 'rollup';

import { logger, slugify, syncResolve } from '@wyw-in-js/shared';
import type { PluginOptions, Preprocessor, Result } from '@wyw-in-js/transform';
import {
getFileIdx,
transform,
TransformCacheCollection,
} from '@wyw-in-js/transform';

type RollupPluginOptions = {
exclude?: string | string[];
include?: string | string[];
preprocessor?: Preprocessor;
sourceMap?: boolean;
} & Partial<PluginOptions>;

export default function wywInJS({
exclude,
include,
preprocessor,
sourceMap,
...rest
}: RollupPluginOptions = {}): Plugin {
const filter = createFilter(include, exclude);
const cssLookup: { [key: string]: string } = {};
const cache = new TransformCacheCollection();
const emptyConfig = {};

const plugin: Plugin = {
name: 'wyw-in-js',
load(id: string) {
return cssLookup[id];
},
/* eslint-disable-next-line consistent-return */
resolveId(importee: string) {
if (importee in cssLookup) return importee;
},
async transform(
code: string,
id: string
): Promise<{ code: string; map: Result['sourceMap'] } | undefined> {
// Do not transform ignored and generated files
if (!filter(id) || id in cssLookup) return;

const log = logger.extend('rollup').extend(getFileIdx(id));

log('init %s', id);

const asyncResolve = async (
what: string,
importer: string,
stack: string[]
) => {
const resolved = await this.resolve(what, importer);
if (resolved) {
if (resolved.external) {
// If module is marked as external, Rollup will not resolve it,
// so we need to resolve it ourselves with default resolver
const resolvedId = syncResolve(what, importer, stack);
log("resolve: ✅ '%s'@'%s -> %O\n%s", what, importer, resolved);
return resolvedId;
}

log("resolve: ✅ '%s'@'%s -> %O\n%s", what, importer, resolved);

// Vite adds param like `?v=667939b3` to cached modules
const resolvedId = resolved.id.split('?')[0];

if (resolvedId.startsWith('\0')) {
// \0 is a special character in Rollup that tells Rollup to not include this in the bundle
// https://rollupjs.org/guide/en/#outputexports
return null;
}

return resolvedId;
}

log("resolve: ❌ '%s'@'%s", what, importer);
throw new Error(`Could not resolve ${what}`);
};

const transformServices = {
options: {
filename: id,
root: process.cwd(),
preprocessor,
pluginOptions: rest,
},
cache,
};

const result = await transform(
transformServices,
code,
asyncResolve,
emptyConfig
);

if (!result.cssText) return;

let { cssText } = result;

const slug = slugify(cssText);
const filename = `${id.replace(/\.[jt]sx?$/, '')}_${slug}.css`;

if (sourceMap && result.cssSourceMapText) {
const map = Buffer.from(result.cssSourceMapText).toString('base64');
cssText += `/*# sourceMappingURL=data:application/json;base64,${map}*/`;
}

cssLookup[filename] = cssText;

result.code += `\nimport ${JSON.stringify(filename)};\n`;

/* eslint-disable-next-line consistent-return */
return { code: result.code, map: result.sourceMap };
},
};

return new Proxy<Plugin>(plugin, {
get(target, prop) {
return target[prop as keyof Plugin];
},

getOwnPropertyDescriptor(target, prop) {
return Object.getOwnPropertyDescriptor(target, prop as keyof Plugin);
},

ownKeys() {
// Rollup doesn't ask config about its own keys, so it is Vite.

throw new Error(
'You are trying to use @wyw-in-js/rollup with Vite. Please use @wyw-in-js/vite instead.'
);
},
});
}
4 changes: 4 additions & 0 deletions packages/rollup/tsconfig.eslint.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"extends": "./tsconfig.json",
"include": ["./src/**/*.ts"]
}
13 changes: 13 additions & 0 deletions packages/rollup/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"extends": "@wyw-in-js/ts-config/node.json",
"files": [],
"include": [],
"references": [
{
"path": "./tsconfig.lib.json"
},
{
"path": "./tsconfig.spec.json"
}
]
}
8 changes: 8 additions & 0 deletions packages/rollup/tsconfig.lib.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
"outDir": "./types"
},
"exclude": ["**/__tests__/*"],
"include": ["./src/**/*.ts"]
}
7 changes: 7 additions & 0 deletions packages/rollup/tsconfig.spec.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
"noEmit": true
},
"include": ["**/__tests__/*"]
}
1 change: 1 addition & 0 deletions packages/transform/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ export { withDefaultServices } from './transform/helpers/withDefaultServices';
export type { Services } from './transform/types';
export type { EventEmitter } from './utils/EventEmitter';
export { isNode } from './utils/isNode';
export { getFileIdx } from './utils/getFileIdx';
export { getTagProcessor } from './utils/getTagProcessor';
export { getVisitorKeys } from './utils/getVisitorKeys';
export type { VisitorKeys } from './utils/getVisitorKeys';
Expand Down
62 changes: 60 additions & 2 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 6f8ae08

Please sign in to comment.