Skip to content

Commit

Permalink
feat: catch transform css error (#9)
Browse files Browse the repository at this point in the history
  • Loading branch information
noyobo committed Jun 6, 2023
1 parent cbba98a commit df92aa8
Show file tree
Hide file tree
Showing 5 changed files with 80 additions and 12 deletions.
11 changes: 11 additions & 0 deletions __tests__/css-error/index.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
.app {
padding: 20px;
user-select: none;
}

.title {
font-size: var(-- 15px, 15px);
color: #000;
}


11 changes: 11 additions & 0 deletions __tests__/css-error/index.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import styles from './index.css';

import React from 'react';
import { createRoot } from 'react-dom/client';
const App = () => (
<div className={'app'}>
<h1 className={'title'}>Hello World</h1>
</div>
);

createRoot(document.getElementById('root')).render(<App />);
19 changes: 19 additions & 0 deletions __tests__/css-error/index.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import path from 'path';
import { removeComments, runTest } from '../runTest';
import fse from 'fs-extra';
import { formatMessages } from 'esbuild';

const OUTPUT_HTML = !!process.env.OUTPUT_HTML;

describe(path.basename(path.dirname(__filename)), function () {
it('style-loader', async function () {
const output = path.resolve(__dirname, 'output');
fse.removeSync(output);
await runTest([path.resolve(__dirname, './index.jsx')], output).catch((error) => {
formatMessages(error.errors, { kind: 'error', color: false }).then((res) => {
expect(res.length).toBe(1);
expect(res[0]).toContain('[ERROR] Unexpected token Dimension');
});
});
});
});
46 changes: 34 additions & 12 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
import { OnResolveArgs, Plugin } from 'esbuild';
import { OnResolveArgs, PartialMessage, Plugin } from 'esbuild';
import PATH from 'path';
import browserslist from 'browserslist';
import { CSSModulesConfig, transform } from 'lightningcss';
import { readFile } from 'fs/promises';
import qs from 'query-string';
import deepmerge from 'deepmerge';

import { transformLess } from './transform-less';
import { codeWithSourceMap, cssExportsToJs, generateTargets, parsePath, resolvePath } from './utils';
import { codeWithSourceMap, cssExportsToJs, generateTargets, parsePath, replaceExtension, resolvePath } from './utils';
import { convertLessError } from './less-utils';
import { transformSass } from './transform-sass';
import { TransformResult } from './types';
Expand Down Expand Up @@ -112,15 +111,38 @@ export const styleLoader = (options: StyleLoaderOptions = {}): Plugin => {
};
}

const { code, map, exports } = transform({
targets: targets,
inputSourceMap: cssSourceMap,
sourceMap: true,
filename: args.path,
cssModules: enableCssModules ? opts.cssModules : false,
code: Buffer.from(cssContent),
});
// TODO: throw error if css is invalid
let transformResult;

try {
transformResult = transform({
targets: targets,
inputSourceMap: cssSourceMap,
sourceMap: true,
filename: args.path,
cssModules: enableCssModules ? opts.cssModules : false,
code: Buffer.from(cssContent),
});
} catch (error) {
const { loc, fileName, source } = error;
const lines = source.split('\n');
const lineText = lines[loc.line - 1];
return {
errors: [
{
text: error.message,
location: {
file: replaceExtension(fileName, '.css'),
line: loc.line,
column: loc.column,
lineText,
},
} as PartialMessage,
],
resolveDir: PATH.dirname(args.path),
};
}

const { code, map, exports } = transformResult;

if (buildOptions.sourcemap && map) {
cssContent = codeWithSourceMap(code.toString(), map.toString());
Expand Down
5 changes: 5 additions & 0 deletions src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,3 +69,8 @@ export async function resolvePath(args: OnResolveArgs, build: PluginBuild) {
export const generateTargets = (queries: string) => {
return browserslistToTargets(browserslist(queries));
};

export const replaceExtension = (file: string, ext: string) => {
const extName = PATH.extname(file);
return file.slice(0, file.length - extName.length) + ext;
};

0 comments on commit df92aa8

Please sign in to comment.