mirror of
https://gitee.com/nocobase/nocobase.git
synced 2025-07-01 18:52:20 +08:00
fix: create-nocobase-app yarn dev error (#5697)
This commit is contained in:
parent
92e4643842
commit
327b5bd6c9
@ -17,7 +17,6 @@ import { libInjectCss } from 'vite-plugin-lib-inject-css';
|
||||
|
||||
import { globExcludeFiles } from './constant';
|
||||
import { PkgLog, UserConfig, getEnvDefine } from './utils';
|
||||
import { rspack } from '@rspack/core';
|
||||
|
||||
export async function buildClient(cwd: string, userConfig: UserConfig, sourcemap: boolean = false, log: PkgLog) {
|
||||
log('build client');
|
||||
@ -30,7 +29,7 @@ export async function buildClient(cwd: string, userConfig: UserConfig, sourcemap
|
||||
return true;
|
||||
};
|
||||
await buildClientEsm(cwd, userConfig, sourcemap, external, log);
|
||||
// await buildClientLib(cwd, userConfig, sourcemap, external, log);
|
||||
await buildClientLib(cwd, userConfig, sourcemap, external, log);
|
||||
await buildLocale(cwd, userConfig, log);
|
||||
}
|
||||
|
||||
@ -40,170 +39,31 @@ function buildClientEsm(cwd: string, userConfig: UserConfig, sourcemap: boolean,
|
||||
log('build client esm');
|
||||
const entry = path.join(cwd, 'src/index.ts').replaceAll(/\\/g, '/');
|
||||
const outDir = path.resolve(cwd, 'es');
|
||||
|
||||
return rspack({
|
||||
entry: {
|
||||
index: entry,
|
||||
},
|
||||
output: {
|
||||
path: outDir,
|
||||
library: {
|
||||
type: 'module',
|
||||
return viteBuild(
|
||||
userConfig.modifyViteConfig({
|
||||
mode: process.env.NODE_ENV || 'production',
|
||||
define: getEnvDefine(),
|
||||
build: {
|
||||
minify: process.env.NODE_ENV === 'production',
|
||||
outDir,
|
||||
cssCodeSplit: true,
|
||||
emptyOutDir: true,
|
||||
sourcemap,
|
||||
lib: {
|
||||
entry,
|
||||
formats: ['es'],
|
||||
fileName: 'index',
|
||||
},
|
||||
target: ['es2015', 'edge88', 'firefox78', 'chrome87', 'safari14'],
|
||||
rollupOptions: {
|
||||
cache: true,
|
||||
treeshake: true,
|
||||
external,
|
||||
},
|
||||
},
|
||||
clean: true,
|
||||
},
|
||||
target: ['es2015', 'web'],
|
||||
mode: process.env.NODE_ENV === 'production' ? 'production' : 'development',
|
||||
optimization: {
|
||||
minimize: process.env.NODE_ENV === 'production',
|
||||
moduleIds: 'deterministic',
|
||||
sideEffects: true,
|
||||
},
|
||||
resolve: {
|
||||
tsConfig: path.join(process.cwd(), 'tsconfig.json'),
|
||||
extensions: ['.js', '.jsx', '.ts', '.tsx', '.json', '.less', '.css'],
|
||||
},
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.less$/,
|
||||
use: [
|
||||
{ loader: 'style-loader' },
|
||||
{ loader: 'css-loader' },
|
||||
{ loader: require.resolve('less-loader') },
|
||||
{
|
||||
loader: 'postcss-loader',
|
||||
options: {
|
||||
postcssOptions: {
|
||||
plugins: {
|
||||
'postcss-preset-env': {
|
||||
browsers: ['last 2 versions', '> 1%', 'cover 99.5%', 'not dead'],
|
||||
},
|
||||
autoprefixer: {},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
type: 'javascript/auto',
|
||||
},
|
||||
{
|
||||
test: /\.css$/,
|
||||
use: [
|
||||
'style-loader',
|
||||
'css-loader',
|
||||
{
|
||||
loader: 'postcss-loader',
|
||||
options: {
|
||||
postcssOptions: {
|
||||
plugins: {
|
||||
'postcss-preset-env': {
|
||||
browsers: ['last 2 versions', '> 1%', 'cover 99.5%', 'not dead'],
|
||||
},
|
||||
autoprefixer: {},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
type: 'javascript/auto',
|
||||
},
|
||||
{
|
||||
test: /\.(png|jpe?g|gif)$/i,
|
||||
type: 'asset',
|
||||
},
|
||||
{
|
||||
test: /\.svg$/i,
|
||||
issuer: /\.[jt]sx?$/,
|
||||
use: ['@svgr/webpack'],
|
||||
},
|
||||
{
|
||||
test: /\.jsx$/,
|
||||
exclude: /[\\/]node_modules[\\/]/,
|
||||
loader: 'builtin:swc-loader',
|
||||
options: {
|
||||
sourceMap: true,
|
||||
jsc: {
|
||||
parser: {
|
||||
syntax: 'ecmascript',
|
||||
jsx: true,
|
||||
},
|
||||
target: 'es5',
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
test: /\.tsx$/,
|
||||
exclude: /[\\/]node_modules[\\/]/,
|
||||
loader: 'builtin:swc-loader',
|
||||
options: {
|
||||
sourceMap: true,
|
||||
jsc: {
|
||||
parser: {
|
||||
syntax: 'typescript',
|
||||
tsx: true,
|
||||
},
|
||||
target: 'es5',
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
test: /\.ts$/,
|
||||
exclude: /[\\/]node_modules[\\/]/,
|
||||
loader: 'builtin:swc-loader',
|
||||
options: {
|
||||
sourceMap: true,
|
||||
jsc: {
|
||||
parser: {
|
||||
syntax: 'typescript',
|
||||
},
|
||||
target: 'es5',
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
externals: [
|
||||
function ({ request }, callback) {
|
||||
if (external(request)) {
|
||||
return callback(null, true);
|
||||
}
|
||||
callback();
|
||||
}
|
||||
],
|
||||
plugins: [
|
||||
new rspack.DefinePlugin(getEnvDefine()),
|
||||
],
|
||||
stats: 'errors-warnings',
|
||||
});
|
||||
|
||||
// const entry = path.join(cwd, 'src/index.ts').replaceAll(/\\/g, '/');
|
||||
// const outDir = path.resolve(cwd, 'es');
|
||||
// return viteBuild(
|
||||
// userConfig.modifyViteConfig({
|
||||
// mode: process.env.NODE_ENV || 'production',
|
||||
// define: getEnvDefine(),
|
||||
// build: {
|
||||
// minify: process.env.NODE_ENV === 'production',
|
||||
// outDir,
|
||||
// cssCodeSplit: true,
|
||||
// emptyOutDir: true,
|
||||
// sourcemap,
|
||||
// lib: {
|
||||
// entry,
|
||||
// formats: ['es'],
|
||||
// fileName: 'index',
|
||||
// },
|
||||
// target: ['es2015', 'edge88', 'firefox78', 'chrome87', 'safari14'],
|
||||
// rollupOptions: {
|
||||
// cache: true,
|
||||
// treeshake: true,
|
||||
// external,
|
||||
// },
|
||||
// },
|
||||
// plugins: [react(), libInjectCss()],
|
||||
// }),
|
||||
// );
|
||||
plugins: [react(), libInjectCss()],
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
async function buildClientLib(
|
||||
|
@ -11,7 +11,6 @@ import path from 'path';
|
||||
import { PkgLog, UserConfig, getEnvDefine } from './utils';
|
||||
import { build as viteBuild } from 'vite';
|
||||
import fg from 'fast-glob';
|
||||
import { rspack } from '@rspack/core';
|
||||
|
||||
const clientExt = '.{ts,tsx,js,jsx}';
|
||||
|
||||
@ -61,158 +60,28 @@ function build(
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
return rspack({
|
||||
entry: {
|
||||
index: entry,
|
||||
},
|
||||
output: {
|
||||
path: outDir,
|
||||
library: {
|
||||
type: 'module',
|
||||
return viteBuild(
|
||||
userConfig.modifyViteConfig({
|
||||
mode: process.env.NODE_ENV || 'production',
|
||||
define: getEnvDefine(),
|
||||
build: {
|
||||
minify: false,
|
||||
outDir,
|
||||
cssCodeSplit: true,
|
||||
emptyOutDir: true,
|
||||
sourcemap,
|
||||
lib: {
|
||||
entry,
|
||||
formats: ['es'],
|
||||
fileName: 'index',
|
||||
},
|
||||
target: ['node16'],
|
||||
rollupOptions: {
|
||||
cache: true,
|
||||
treeshake: true,
|
||||
external,
|
||||
},
|
||||
},
|
||||
clean: true,
|
||||
},
|
||||
target: ['node16'],
|
||||
mode: process.env.NODE_ENV === 'production' ? 'production' : 'development',
|
||||
resolve: {
|
||||
tsConfig: path.join(process.cwd(), 'tsconfig.json'),
|
||||
extensions: ['.js', '.jsx', '.ts', '.tsx', '.json', '.less', '.css'],
|
||||
},
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.less$/,
|
||||
use: [
|
||||
{ loader: 'style-loader' },
|
||||
{ loader: 'css-loader' },
|
||||
{ loader: require.resolve('less-loader') },
|
||||
{
|
||||
loader: 'postcss-loader',
|
||||
options: {
|
||||
postcssOptions: {
|
||||
plugins: {
|
||||
'postcss-preset-env': {
|
||||
browsers: ['last 2 versions', '> 1%', 'cover 99.5%', 'not dead'],
|
||||
},
|
||||
autoprefixer: {},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
type: 'javascript/auto',
|
||||
},
|
||||
{
|
||||
test: /\.css$/,
|
||||
use: [
|
||||
'style-loader',
|
||||
'css-loader',
|
||||
{
|
||||
loader: 'postcss-loader',
|
||||
options: {
|
||||
postcssOptions: {
|
||||
plugins: {
|
||||
'postcss-preset-env': {
|
||||
browsers: ['last 2 versions', '> 1%', 'cover 99.5%', 'not dead'],
|
||||
},
|
||||
autoprefixer: {},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
type: 'javascript/auto',
|
||||
},
|
||||
{
|
||||
test: /\.(png|jpe?g|gif)$/i,
|
||||
type: 'asset',
|
||||
},
|
||||
{
|
||||
test: /\.svg$/i,
|
||||
issuer: /\.[jt]sx?$/,
|
||||
use: ['@svgr/webpack'],
|
||||
},
|
||||
{
|
||||
test: /\.jsx$/,
|
||||
exclude: /[\\/]node_modules[\\/]/,
|
||||
loader: 'builtin:swc-loader',
|
||||
options: {
|
||||
sourceMap: true,
|
||||
jsc: {
|
||||
parser: {
|
||||
syntax: 'ecmascript',
|
||||
jsx: true,
|
||||
},
|
||||
target: 'es5',
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
test: /\.tsx$/,
|
||||
exclude: /[\\/]node_modules[\\/]/,
|
||||
loader: 'builtin:swc-loader',
|
||||
options: {
|
||||
sourceMap: true,
|
||||
jsc: {
|
||||
parser: {
|
||||
syntax: 'typescript',
|
||||
tsx: true,
|
||||
},
|
||||
target: 'es5',
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
test: /\.ts$/,
|
||||
exclude: /[\\/]node_modules[\\/]/,
|
||||
loader: 'builtin:swc-loader',
|
||||
options: {
|
||||
sourceMap: true,
|
||||
jsc: {
|
||||
parser: {
|
||||
syntax: 'typescript',
|
||||
},
|
||||
target: 'es5',
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
externals: [
|
||||
function ({ request }, callback) {
|
||||
if (external(request)) {
|
||||
return callback(null, true);
|
||||
}
|
||||
callback();
|
||||
},
|
||||
],
|
||||
plugins: [new rspack.DefinePlugin(getEnvDefine())],
|
||||
stats: 'errors-warnings',
|
||||
});
|
||||
|
||||
// return viteBuild(
|
||||
// userConfig.modifyViteConfig({
|
||||
// mode: process.env.NODE_ENV || 'production',
|
||||
// define: getEnvDefine(),
|
||||
// build: {
|
||||
// minify: false,
|
||||
// outDir,
|
||||
// cssCodeSplit: true,
|
||||
// emptyOutDir: true,
|
||||
// sourcemap,
|
||||
// lib: {
|
||||
// entry,
|
||||
// formats: ['es'],
|
||||
// fileName: 'index',
|
||||
// },
|
||||
// target: ['node16'],
|
||||
// rollupOptions: {
|
||||
// cache: true,
|
||||
// treeshake: true,
|
||||
// external,
|
||||
// },
|
||||
// },
|
||||
// }),
|
||||
// );
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
@ -16,10 +16,9 @@ import path from 'path';
|
||||
import { build as tsupBuild } from 'tsup';
|
||||
import { build as viteBuild } from 'vite';
|
||||
import cssInjectedByJsPlugin from 'vite-plugin-css-injected-by-js';
|
||||
import { rspack } from '@rspack/core';
|
||||
|
||||
import { EsbuildSupportExts, globExcludeFiles } from './constant';
|
||||
import { PkgLog, UserConfig, getPackageJson } from './utils';
|
||||
import { PkgLog, UserConfig, getEnvDefine, getPackageJson } from './utils';
|
||||
import {
|
||||
buildCheck,
|
||||
checkFileSize,
|
||||
@ -131,7 +130,6 @@ const external = [
|
||||
'ahooks',
|
||||
'lodash',
|
||||
'china-division',
|
||||
'file-saver',
|
||||
];
|
||||
const pluginPrefix = (
|
||||
process.env.PLUGIN_PACKAGE_PREFIX || '@nocobase/plugin-,@nocobase/preset-,@nocobase/plugin-pro-'
|
||||
@ -196,9 +194,7 @@ export async function buildServerDeps(cwd: string, serverFiles: string[], log: P
|
||||
if (excludePackages.length) {
|
||||
tips.push(`These packages ${chalk.yellow(excludePackages.join(', '))} will be ${chalk.italic('exclude')}.`);
|
||||
}
|
||||
tips.push(
|
||||
`For more information, please refer to: ${chalk.blue('https://docs.nocobase.com/development/others/deps')}.`,
|
||||
);
|
||||
tips.push(`For more information, please refer to: ${chalk.blue('https://docs.nocobase.com/development/deps')}.`);
|
||||
log(tips.join(' '));
|
||||
|
||||
if (!includePackages.length) return;
|
||||
@ -322,205 +318,51 @@ export async function buildPluginClient(cwd: string, userConfig: UserConfig, sou
|
||||
|
||||
const globals = excludePackages.reduce<Record<string, string>>((prev, curr) => {
|
||||
if (curr.startsWith('@nocobase')) {
|
||||
prev[`${curr}/client`] = `${curr}/client`;
|
||||
prev[`${curr}/client`] = curr;
|
||||
}
|
||||
prev[curr] = curr;
|
||||
return prev;
|
||||
}, {});
|
||||
|
||||
const entry = fg.globSync('index.{ts,tsx,js,jsx}', { absolute: false, cwd: path.join(cwd, 'src/client') });
|
||||
const entry = fg.globSync('src/client/index.{ts,tsx,js,jsx}', { absolute: true, cwd });
|
||||
const outputFileName = 'index.js';
|
||||
const compiler = rspack({
|
||||
mode: 'production',
|
||||
// mode: "development",
|
||||
context: cwd,
|
||||
entry: './src/client/' + entry[0],
|
||||
target: ['web', 'es5'],
|
||||
output: {
|
||||
path: outDir,
|
||||
filename: outputFileName,
|
||||
publicPath: `/static/plugins/${packageJson.name}/dist/client/`,
|
||||
clean: true,
|
||||
library: {
|
||||
name: packageJson.name,
|
||||
type: 'umd',
|
||||
umdNamedDefine: true,
|
||||
|
||||
await viteBuild(
|
||||
userConfig.modifyViteConfig({
|
||||
mode: process.env.NODE_ENV || 'production',
|
||||
define: getEnvDefine(),
|
||||
logLevel: 'warn',
|
||||
build: {
|
||||
minify: process.env.NODE_ENV === 'production',
|
||||
outDir,
|
||||
cssCodeSplit: false,
|
||||
emptyOutDir: true,
|
||||
sourcemap,
|
||||
lib: {
|
||||
entry,
|
||||
formats: ['umd'],
|
||||
name: packageJson.name,
|
||||
fileName: () => outputFileName,
|
||||
},
|
||||
target: ['es2015', 'edge88', 'firefox78', 'chrome87', 'safari14'],
|
||||
rollupOptions: {
|
||||
cache: true,
|
||||
external: [...Object.keys(globals), 'react', 'react/jsx-runtime'],
|
||||
output: {
|
||||
exports: 'named',
|
||||
globals: {
|
||||
react: 'React',
|
||||
'react/jsx-runtime': 'jsxRuntime',
|
||||
...globals,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
resolve: {
|
||||
tsConfig: path.join(process.cwd(), 'tsconfig.json'),
|
||||
extensions: ['.js', '.jsx', '.ts', '.tsx', '.json', '.less', '.css'],
|
||||
},
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.less$/,
|
||||
use: [
|
||||
{ loader: 'style-loader' },
|
||||
{ loader: 'css-loader' },
|
||||
{ loader: require.resolve('less-loader') },
|
||||
{
|
||||
loader: 'postcss-loader',
|
||||
options: {
|
||||
postcssOptions: {
|
||||
plugins: {
|
||||
'postcss-preset-env': {
|
||||
browsers: ['last 2 versions', '> 1%', 'cover 99.5%', 'not dead'],
|
||||
},
|
||||
autoprefixer: {},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
type: 'javascript/auto',
|
||||
},
|
||||
{
|
||||
test: /\.css$/,
|
||||
use: [
|
||||
'style-loader',
|
||||
'css-loader',
|
||||
{
|
||||
loader: 'postcss-loader',
|
||||
options: {
|
||||
postcssOptions: {
|
||||
plugins: {
|
||||
'postcss-preset-env': {
|
||||
browsers: ['last 2 versions', '> 1%', 'cover 99.5%', 'not dead'],
|
||||
},
|
||||
autoprefixer: {},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
type: 'javascript/auto',
|
||||
},
|
||||
{
|
||||
test: /\.(png|jpe?g|gif)$/i,
|
||||
type: 'asset',
|
||||
},
|
||||
{
|
||||
test: /\.svg$/i,
|
||||
issuer: /\.[jt]sx?$/,
|
||||
use: ['@svgr/webpack'],
|
||||
},
|
||||
{
|
||||
test: /\.jsx$/,
|
||||
exclude: /[\\/]node_modules[\\/]/,
|
||||
loader: 'builtin:swc-loader',
|
||||
options: {
|
||||
sourceMap: true,
|
||||
jsc: {
|
||||
parser: {
|
||||
syntax: 'ecmascript',
|
||||
jsx: true,
|
||||
},
|
||||
target: 'es5',
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
test: /\.tsx$/,
|
||||
exclude: /[\\/]node_modules[\\/]/,
|
||||
loader: 'builtin:swc-loader',
|
||||
options: {
|
||||
sourceMap: true,
|
||||
jsc: {
|
||||
parser: {
|
||||
syntax: 'typescript',
|
||||
tsx: true,
|
||||
},
|
||||
target: 'es5',
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
test: /\.ts$/,
|
||||
exclude: /[\\/]node_modules[\\/]/,
|
||||
loader: 'builtin:swc-loader',
|
||||
options: {
|
||||
sourceMap: true,
|
||||
jsc: {
|
||||
parser: {
|
||||
syntax: 'typescript',
|
||||
},
|
||||
target: 'es5',
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
plugins: [
|
||||
new rspack.DefinePlugin({
|
||||
'process.env.NODE_ENV': JSON.stringify('production'),
|
||||
}),
|
||||
],
|
||||
node: {
|
||||
global: true,
|
||||
},
|
||||
externals: {
|
||||
react: 'React',
|
||||
lodash: 'lodash',
|
||||
// 'react/jsx-runtime': 'jsxRuntime',
|
||||
...globals,
|
||||
},
|
||||
stats: 'errors-warnings',
|
||||
});
|
||||
plugins: [react(), cssInjectedByJsPlugin({ styleId: packageJson.name })],
|
||||
}),
|
||||
);
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
compiler.run((err, stats) => {
|
||||
const compilationErrors = stats?.compilation.errors;
|
||||
const infos = stats.toString({
|
||||
colors: true,
|
||||
});
|
||||
if (err || compilationErrors?.length) {
|
||||
reject(err || infos);
|
||||
return;
|
||||
}
|
||||
console.log(infos);
|
||||
resolve(null);
|
||||
});
|
||||
});
|
||||
// await viteBuild(userConfig.modifyViteConfig({
|
||||
// mode: 'production',
|
||||
// define: {
|
||||
// 'process.env.NODE_ENV': JSON.stringify('production'),
|
||||
// },
|
||||
// logLevel: 'warn',
|
||||
// build: {
|
||||
// minify: true,
|
||||
// outDir,
|
||||
// cssCodeSplit: false,
|
||||
// emptyOutDir: true,
|
||||
// sourcemap,
|
||||
// lib: {
|
||||
// entry,
|
||||
// formats: ['umd'],
|
||||
// name: packageJson.name,
|
||||
// fileName: () => outputFileName,
|
||||
// },
|
||||
// target: ['es2015', 'edge88', 'firefox78', 'chrome87', 'safari14'],
|
||||
// rollupOptions: {
|
||||
// cache: true,
|
||||
// external: [...Object.keys(globals), 'react', 'react/jsx-runtime'],
|
||||
// output: {
|
||||
// exports: 'named',
|
||||
// globals: {
|
||||
// react: 'React',
|
||||
// 'react/jsx-runtime': 'jsxRuntime',
|
||||
// ...globals,
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// plugins: [
|
||||
// react(),
|
||||
// cssInjectedByJsPlugin({ styleId: packageJson.name }),
|
||||
// ],
|
||||
// }));
|
||||
|
||||
// checkFileSize(outDir, log);
|
||||
checkFileSize(outDir, log);
|
||||
}
|
||||
|
||||
export async function buildPlugin(cwd: string, userConfig: UserConfig, sourcemap: boolean, log: PkgLog) {
|
||||
|
@ -41,7 +41,6 @@ import * as ReactRouter from 'react-router';
|
||||
import * as ReactRouterDom from 'react-router-dom';
|
||||
import jsxRuntime from 'react/jsx-runtime';
|
||||
import * as nocobaseClient from '../../index';
|
||||
import * as FileSaver from 'file-saver';
|
||||
|
||||
import type { RequireJS } from './requirejs';
|
||||
|
||||
@ -102,5 +101,4 @@ export function defineGlobalDeps(requirejs: RequireJS) {
|
||||
requirejs.define('ahooks', () => ahooks);
|
||||
requirejs.define('@emotion/css', () => emotionCss);
|
||||
requirejs.define('dayjs', () => dayjs);
|
||||
requirejs.define('file-saver', () => FileSaver);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user