-
Notifications
You must be signed in to change notification settings - Fork 2.7k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* feat: icons * chore: improve test * feat: base build implemention * chore: comments * feat: collect icons with build * feat: support generate svgr from collection and icon name * feat: complete the basic version, fa iconset builtin only * fix: don't generate bundle output, it's conflicted with mfsu eager mode
- Loading branch information
Showing
18 changed files
with
681 additions
and
48 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export const alias = 'alias-with-@'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export const alias3 = 'alias-3'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export const foo = 'foo'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
import React from 'react'; | ||
import { foo } from './foo'; | ||
// @ts-ignore | ||
import { jsx } from './jsx'; | ||
// @ts-ignore | ||
import { bar } from 'bar'; | ||
import './a.less'; | ||
import './a.less?global'; | ||
import './a.jpg'; | ||
import './a.png'; | ||
import './a.sass'; | ||
import './a.css'; | ||
import './a.json'; | ||
// @ts-ignore | ||
import json from 'ggg/a.json'; | ||
// @ts-ignore | ||
import antd from '@alipay/bigfish/antd'; | ||
// @ts-ignore | ||
import { alias } from '@/alias'; | ||
import 'alias-1'; | ||
// @ts-ignore | ||
import { alias3, Icon } from 'alias-3'; | ||
|
||
console.log(1, foo, jsx, bar, json, antd, alias, alias3); | ||
export function App() { | ||
return ( | ||
<> | ||
<Icon name="xxx" /> | ||
<Icon name="xxx2" /> | ||
<Icon name="xxx222" /> | ||
</> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
|
||
export const jsx = 'jsx'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
79 changes: 79 additions & 0 deletions
79
packages/preset-umi/src/features/icons/buildForIconExtract.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
import esbuild from '@umijs/bundler-utils/compiled/esbuild'; | ||
import { esbuildExternalPlugin } from './esbuildExternalPlugin'; | ||
import path from 'path'; | ||
import { esbuildAliasPlugin } from './esbuildAliasPlugin'; | ||
import { esbuildCollectIconPlugin } from './esbuildCollectIconPlugin'; | ||
import { logger } from '@umijs/utils'; | ||
|
||
export async function buildForIconExtract(opts: { | ||
entryPoints: string[]; | ||
watch?: | ||
| { | ||
onRebuildSuccess(): void; | ||
} | ||
| false; | ||
config?: { alias?: any }; | ||
}) { | ||
const icons: Set<string> = new Set(); | ||
await esbuild.build({ | ||
format: 'esm', | ||
platform: 'browser', | ||
target: 'esnext', | ||
loader: { | ||
'.js': 'jsx', | ||
'.jsx': 'jsx', | ||
'.ts': 'ts', | ||
'.tsx': 'tsx', | ||
}, | ||
watch: !!opts.watch && { | ||
onRebuild(err) { | ||
if (err) { | ||
logger.error(`[icons] build failed: ${err}`); | ||
} else { | ||
if (opts.watch) { | ||
opts.watch.onRebuildSuccess(); | ||
} | ||
} | ||
}, | ||
}, | ||
// do I need this? | ||
// incremental: true, | ||
bundle: true, | ||
logLevel: 'error', | ||
entryPoints: opts.entryPoints, | ||
write: false, | ||
outdir: path.join(path.dirname(opts.entryPoints[0]), 'out'), | ||
plugins: [ | ||
esbuildAliasPlugin({ alias: opts.config?.alias || {} }), | ||
esbuildExternalPlugin(), | ||
esbuildCollectIconPlugin({ | ||
icons, | ||
}), | ||
], | ||
}); | ||
return icons; | ||
} | ||
|
||
// const baseDir = path.join(__dirname, '../../../fixtures/icons/normal'); | ||
// buildForIconExtract({ | ||
// entryPoints: [path.join(baseDir, 'index.tsx')], | ||
// config: { | ||
// alias: { | ||
// '@': path.join(baseDir, '@'), | ||
// 'alias-1': 'alias-2', | ||
// 'alias-3$': path.join(baseDir, 'alias-3.ts'), | ||
// }, | ||
// }, | ||
// watch: { | ||
// onRebuildSuccess(icons) { | ||
// console.log('icons', icons); | ||
// }, | ||
// }, | ||
// }) | ||
// .then((icons) => { | ||
// console.log('done'); | ||
// console.log(icons); | ||
// }) | ||
// .catch((e) => { | ||
// console.error(e); | ||
// }); |
83 changes: 83 additions & 0 deletions
83
packages/preset-umi/src/features/icons/esbuildAliasPlugin.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
import type { Plugin } from '@umijs/bundler-utils/compiled/esbuild'; | ||
import { existsSync, statSync } from 'fs'; | ||
import enhancedResolve from 'enhanced-resolve'; | ||
|
||
const resolver = enhancedResolve.create({ | ||
mainFields: ['module', 'browser', 'main'], | ||
extensions: ['.json', '.js', '.jsx', '.ts', '.tsx', '.cjs', '.mjs'], | ||
// TODO: support exports | ||
exportsFields: [], | ||
}); | ||
|
||
async function resolve(context: string, path: string): Promise<string> { | ||
return new Promise((resolve, reject) => { | ||
resolver(context, path, (err: Error, result: string) => | ||
err ? reject(err) : resolve(result), | ||
); | ||
}); | ||
} | ||
|
||
function sortByAffix(opts: { keys: string[]; affix: string }) { | ||
return opts.keys.sort((a, b) => { | ||
if (a.endsWith(opts.affix) && b.endsWith(opts.affix)) return 0; | ||
if (a.endsWith(opts.affix)) return -1; | ||
if (b.endsWith(opts.affix)) return 1; | ||
else return 0; | ||
}); | ||
} | ||
|
||
function addSlashAffix(key: string) { | ||
return key.endsWith('/') ? key : `${key}/`; | ||
} | ||
|
||
export function esbuildAliasPlugin(opts: { | ||
alias: Record<string, string>; | ||
}): Plugin { | ||
return { | ||
name: 'esbuildExternalPlugin', | ||
setup(build) { | ||
// only absolute alias should be resolved | ||
// node deps alias should be filtered, and mark as externals with other plugins | ||
sortByAffix({ keys: Object.keys(opts.alias), affix: '$' }) | ||
.filter((key) => { | ||
return ( | ||
opts.alias[key].startsWith('/') && | ||
!opts.alias[key].includes('node_modules') | ||
); | ||
}) | ||
.forEach((key) => { | ||
const value = opts.alias[key]; | ||
|
||
const filter = key.endsWith('$') | ||
? new RegExp(key) | ||
: new RegExp(`${key}$`); | ||
build.onResolve({ filter }, async (args) => { | ||
const path = await resolve( | ||
args.importer, | ||
args.path.replace(filter, value), | ||
); | ||
return { | ||
path, | ||
}; | ||
}); | ||
|
||
if ( | ||
!key.endsWith('/') && | ||
existsSync(value) && | ||
statSync(value).isDirectory() | ||
) { | ||
const filter = new RegExp(`^${addSlashAffix(key)}`); | ||
build.onResolve({ filter }, async (args) => { | ||
const path = await resolve( | ||
args.importer, | ||
args.path.replace(filter, addSlashAffix(value)), | ||
); | ||
return { | ||
path, | ||
}; | ||
}); | ||
} | ||
}); | ||
}, | ||
}; | ||
} |
27 changes: 27 additions & 0 deletions
27
packages/preset-umi/src/features/icons/esbuildCollectIconPlugin.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
import type { Plugin, Loader } from '@umijs/bundler-utils/compiled/esbuild'; | ||
import fs from 'fs'; | ||
import { extractIcons } from './extractIcons'; | ||
|
||
export function esbuildCollectIconPlugin(opts: { icons: Set<string> }): Plugin { | ||
return { | ||
name: 'esbuildCollectIconPlugin', | ||
setup(build) { | ||
const loaders: Loader[] = ['js', 'jsx', 'ts', 'tsx']; | ||
loaders.forEach((loader) => { | ||
const filter = new RegExp(`\\.(${loader})$`); | ||
build.onLoad({ filter }, async (args) => { | ||
const contents = fs.readFileSync(args.path, 'utf-8'); | ||
extractIcons(contents).forEach((icon) => { | ||
// just add | ||
// don't handle delete for dev | ||
opts.icons.add(icon); | ||
}); | ||
return { | ||
contents, | ||
loader, | ||
}; | ||
}); | ||
}); | ||
}, | ||
}; | ||
} |
63 changes: 63 additions & 0 deletions
63
packages/preset-umi/src/features/icons/esbuildExternalPlugin.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
import type { Plugin } from '@umijs/bundler-utils/compiled/esbuild'; | ||
|
||
export function esbuildExternalPlugin(): Plugin { | ||
return { | ||
name: 'esbuildExternalPlugin', | ||
setup(build) { | ||
// externals extensions | ||
externalsExtensions.forEach((ext) => { | ||
// /\.abc?query$/ | ||
const filter = new RegExp(`\.${ext}(\\?.*)?$`); | ||
build.onResolve({ filter }, () => { | ||
return { | ||
external: true, | ||
}; | ||
}); | ||
}); | ||
// external deps | ||
build.onResolve({ filter: /.*/ }, (args) => { | ||
if (args.path.startsWith('.')) { | ||
return null; | ||
} | ||
if (args.kind === 'entry-point') { | ||
return null; | ||
} | ||
if (args.path.startsWith('/') && !args.path.includes('node_modules')) { | ||
return null; | ||
} | ||
return { | ||
external: true, | ||
}; | ||
}); | ||
}, | ||
}; | ||
} | ||
|
||
const externalsExtensions = [ | ||
'aac', | ||
'css', | ||
'less', | ||
'sass', | ||
'scss', | ||
'eot', | ||
'flac', | ||
'gif', | ||
'ico', | ||
'jpeg', | ||
'jpg', | ||
'json', | ||
'md', | ||
'mdx', | ||
'mp3', | ||
'mp4', | ||
'ogg', | ||
'otf', | ||
'png', | ||
'svg', | ||
'ttf', | ||
'wav', | ||
'webm', | ||
'webp', | ||
'woff', | ||
'woff2', | ||
]; |
23 changes: 23 additions & 0 deletions
23
packages/preset-umi/src/features/icons/extractIcons.test.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
import { extractIcons } from './extractIcons'; | ||
|
||
test('normal', () => { | ||
expect(extractIcons(`<Icon icon="foo" />`)).toEqual(['foo']); | ||
}); | ||
|
||
test('with chaos', () => { | ||
expect(extractIcons(`<Icon icon="foo" />`)).toEqual(['foo']); | ||
expect(extractIcons(`<Icon icon='foo' />`)).toEqual(['foo']); | ||
expect(extractIcons(`<Icon bar='bar' icon="foo" hoo />`)).toEqual(['foo']); | ||
expect(extractIcons(`<Icon icon="foo bar" />`)).toEqual(['foo bar']); | ||
}); | ||
|
||
test('multiple', () => { | ||
expect(extractIcons(`<Icon icon="foo" /><Icon icon="bar" />`)).toEqual([ | ||
'foo', | ||
'bar', | ||
]); | ||
}); | ||
|
||
test('only the first icon attribute is valid', () => { | ||
expect(extractIcons(`<Icon icon="foo" icon="bar" />`)).toEqual(['foo']); | ||
}); |
Oops, something went wrong.