mirror of https://github.com/alibaba/ice.git
104 lines
3.2 KiB
TypeScript
104 lines
3.2 KiB
TypeScript
import * as path from 'path';
|
|
import { fileURLToPath } from 'url';
|
|
import fg from 'fast-glob';
|
|
import type { Plugin } from '@ice/app/types';
|
|
|
|
const _dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
|
|
interface PluginOptions {
|
|
// The key of locale content read from the window object.
|
|
localeMessagesKey?: string;
|
|
defaultLocaleKey?: string;
|
|
useCDN?: boolean;
|
|
intlSolution?: 'react-intl' | 'simple';
|
|
}
|
|
|
|
const plugin: Plugin<PluginOptions> = ({
|
|
localeMessagesKey = '__LOCALE_MESSAGES__',
|
|
defaultLocaleKey = '__DEFAULT_LOCALE__',
|
|
useCDN = false,
|
|
intlSolution = 'react-intl',
|
|
} = {}) => ({
|
|
name: 'plugin-intl',
|
|
setup: ({ generator, context, createLogger, watch }) => {
|
|
const { rootDir } = context;
|
|
const logger = createLogger('plugin-intl');
|
|
|
|
const renderLocaleEntry = (localeFiles: string[]) => {
|
|
const locales = [];
|
|
let localeExport = [];
|
|
localeFiles.forEach((file) => {
|
|
const filename = path.basename(file, path.extname(file));
|
|
// `-` is not allowed in import specifier.
|
|
const specifier = filename.replace('-', '_');
|
|
locales.push(`import ${specifier} from '@/locales/${filename}';`);
|
|
localeExport.push(`'${filename}': ${specifier},`);
|
|
});
|
|
|
|
generator.addRenderFile(
|
|
path.join(_dirname, '../templates/locales.ts.ejs'),
|
|
'locales.ts',
|
|
{
|
|
localeMessagesKey,
|
|
defaultLocaleKey,
|
|
localeImport: locales.join('\n'),
|
|
localeExport: localeExport.join('\n '),
|
|
},
|
|
);
|
|
};
|
|
const globRule = 'src/locales/*.{ts,js,json}';
|
|
// Glob all locale files, and generate runtime options.
|
|
const localeFiles = fg.sync(globRule, { cwd: rootDir });
|
|
if (localeFiles.length > 0 && !useCDN) {
|
|
// Filter the entry of locale files.
|
|
const mainEntry = localeFiles.find((file) => file.match(/index\.(ts|js|json)$/));
|
|
let runtimeSource = '';
|
|
if (mainEntry) {
|
|
runtimeSource = `@/locales/${path.basename(mainEntry)}`;
|
|
} else {
|
|
// Create a locale entry file to export all locale files.
|
|
renderLocaleEntry(localeFiles);
|
|
|
|
// Add watch event for locale files added or removed.
|
|
watch.addEvent([/src\/locales/, (event) => {
|
|
if (event === 'unlink' || event === 'add') {
|
|
const files = fg.sync(globRule, { cwd: rootDir });
|
|
renderLocaleEntry(files);
|
|
}
|
|
}]);
|
|
runtimeSource = './locales';
|
|
|
|
generator.addEntryImportAhead({
|
|
source: runtimeSource,
|
|
// @ts-ignore
|
|
}, 'both');
|
|
}
|
|
} else {
|
|
renderLocaleEntry([]);
|
|
generator.addEntryImportAhead({
|
|
source: './locales',
|
|
// @ts-ignore
|
|
}, 'both');
|
|
if (!useCDN) {
|
|
logger.warn('No locale files found, please check the `src/locales` folder.');
|
|
}
|
|
}
|
|
|
|
// Add intl export from ice.
|
|
if (intlSolution === 'simple') {
|
|
generator.addExport({
|
|
specifier: ['intl'],
|
|
source: '@ice/plugin-intl/runtime-simple',
|
|
});
|
|
} else {
|
|
generator.addExport({
|
|
specifier: ['useIntl', 'intl'],
|
|
source: '@ice/plugin-intl/runtime',
|
|
});
|
|
}
|
|
},
|
|
runtime: intlSolution === 'simple' ? '@ice/plugin-intl/runtime-simple' : '@ice/plugin-intl/runtime',
|
|
});
|
|
|
|
export default plugin;
|