mirror of
https://github.com/strapi/strapi.git
synced 2025-11-02 02:44:55 +00:00
Enable plugin development in JS project.
Added loader for ts. Created default tsconfig file Signed-off-by: soupette <cyril@strapi.io>
This commit is contained in:
parent
91cbfef66e
commit
84bd88a230
@ -17,7 +17,8 @@ type Auth = {
|
||||
|
||||
const config: Config = {
|
||||
auth: {
|
||||
logo: 'https://images.unsplash.com/photo-1593642634367-d91a135587b5?ixid=MnwxMjA3fDF8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&ixlib=rb-1.2.1&auto=format&fit=crop&w=750&q=80',
|
||||
logo:
|
||||
'https://images.unsplash.com/photo-1593642634367-d91a135587b5?ixid=MnwxMjA3fDF8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&ixlib=rb-1.2.1&auto=format&fit=crop&w=750&q=80',
|
||||
},
|
||||
head: {
|
||||
favicon:
|
||||
@ -26,7 +27,8 @@ const config: Config = {
|
||||
},
|
||||
locales: ['fr'],
|
||||
menu: {
|
||||
logo: 'https://images.unsplash.com/photo-1593642634367-d91a135587b5?ixid=MnwxMjA3fDF8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&ixlib=rb-1.2.1&auto=format&fit=crop&w=750&q=80',
|
||||
logo:
|
||||
'https://images.unsplash.com/photo-1593642634367-d91a135587b5?ixid=MnwxMjA3fDF8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&ixlib=rb-1.2.1&auto=format&fit=crop&w=750&q=80',
|
||||
},
|
||||
theme,
|
||||
translations: {
|
||||
19
examples/kitchensink-ts/src/admin/tsconfig.json
Normal file
19
examples/kitchensink-ts/src/admin/tsconfig.json
Normal file
@ -0,0 +1,19 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"lib": ["es2019", "es2020.promise", "es2020.bigint", "es2020.string", "DOM"],
|
||||
"noImplicitAny": false,
|
||||
"module": "es2020",
|
||||
"target": "es5",
|
||||
"jsx": "react",
|
||||
"allowJs": true,
|
||||
"moduleResolution": "node",
|
||||
"skipLibCheck": true,
|
||||
"esModuleInterop": true,
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"resolveJsonModule": true,
|
||||
"noEmit": false,
|
||||
"incremental": true
|
||||
},
|
||||
"include": ["../plugins/**/admin/src/**/*", "./"],
|
||||
"exclude": ["node_modules", "**/*.test.js", "*.js"]
|
||||
}
|
||||
39
examples/kitchensink/src/admin/app.js
Normal file
39
examples/kitchensink/src/admin/app.js
Normal file
@ -0,0 +1,39 @@
|
||||
import theme from './extensions/theme';
|
||||
|
||||
const config = {
|
||||
auth: {
|
||||
logo:
|
||||
'https://images.unsplash.com/photo-1593642634367-d91a135587b5?ixid=MnwxMjA3fDF8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&ixlib=rb-1.2.1&auto=format&fit=crop&w=750&q=80',
|
||||
},
|
||||
head: {
|
||||
favicon:
|
||||
'https://images.unsplash.com/photo-1593642634367-d91a135587b5?ixid=MnwxMjA3fDF8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&ixlib=rb-1.2.1&auto=format&fit=crop&w=750&q=80',
|
||||
title: 'Strapi tesrrt',
|
||||
},
|
||||
locales: ['fr', 'de'],
|
||||
menu: {
|
||||
logo:
|
||||
'https://images.unsplash.com/photo-1593642634367-d91a135587b5?ixid=MnwxMjA3fDF8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&ixlib=rb-1.2.1&auto=format&fit=crop&w=750&q=80',
|
||||
},
|
||||
theme,
|
||||
translations: {
|
||||
fr: {
|
||||
'Auth.form.email.label': 'test',
|
||||
Users: 'Utilisateurs',
|
||||
City: 'CITY FRENCH',
|
||||
// Customize the label of the CM table..
|
||||
Id: 'ID french',
|
||||
},
|
||||
},
|
||||
tutorials: false,
|
||||
notifications: { release: false },
|
||||
};
|
||||
|
||||
const bootstrap = app => {
|
||||
console.log(app);
|
||||
};
|
||||
|
||||
export default {
|
||||
config,
|
||||
bootstrap,
|
||||
};
|
||||
23
packages/core/admin/admin/src/tsconfig.json
Normal file
23
packages/core/admin/admin/src/tsconfig.json
Normal file
@ -0,0 +1,23 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"lib": ["es2019", "es2020.promise", "es2020.bigint", "es2020.string", "DOM"],
|
||||
"noImplicitAny": false,
|
||||
"module": "es2020",
|
||||
"target": "es5",
|
||||
"jsx": "react",
|
||||
"allowJs": true,
|
||||
"moduleResolution": "node",
|
||||
"skipLibCheck": true,
|
||||
"esModuleInterop": true,
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"resolveJsonModule": true,
|
||||
"noEmit": false,
|
||||
"incremental": true
|
||||
},
|
||||
"include": [
|
||||
"./",
|
||||
"../../../**/admin/src/**/*",
|
||||
"../../../../plugins/documentation/admin/src/**/*"
|
||||
],
|
||||
"exclude": ["node_modules", "**/*.test.js", "*.js"]
|
||||
}
|
||||
@ -4,7 +4,9 @@ const path = require('path');
|
||||
const fs = require('fs-extra');
|
||||
const webpack = require('webpack');
|
||||
const WebpackDevServer = require('webpack-dev-server');
|
||||
const { isTypeScriptProject } = require('@strapi/typescript-utils');
|
||||
const chalk = require('chalk');
|
||||
|
||||
const {
|
||||
createCacheDir,
|
||||
getCustomWebpackConfig,
|
||||
@ -12,24 +14,20 @@ const {
|
||||
watchAdminFiles,
|
||||
} = require('./utils');
|
||||
|
||||
async function build({
|
||||
appDir,
|
||||
buildDestDir,
|
||||
env,
|
||||
forceBuild,
|
||||
optimize,
|
||||
options,
|
||||
plugins,
|
||||
useTypeScript,
|
||||
}) {
|
||||
const buildAdmin = await shouldBuildAdmin({ appDir, plugins, useTypeScript });
|
||||
async function build({ appDir, buildDestDir, env, forceBuild, optimize, options, plugins }) {
|
||||
const buildAdmin = await shouldBuildAdmin({ appDir, plugins });
|
||||
|
||||
const useTypeScript = await isTypeScriptProject(
|
||||
path.join(appDir, 'src', 'admin'),
|
||||
'tsconfig.json'
|
||||
);
|
||||
|
||||
if (!buildAdmin && !forceBuild) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Create the cache dir containing the front-end files.
|
||||
await createCacheDir({ appDir, plugins, useTypeScript });
|
||||
await createCacheDir({ appDir, plugins });
|
||||
|
||||
const cacheDir = path.resolve(appDir, '.cache');
|
||||
const entry = path.resolve(cacheDir, 'admin', 'src');
|
||||
@ -43,6 +41,12 @@ async function build({
|
||||
|
||||
const pluginsPath = Object.keys(plugins).map(pluginName => plugins[pluginName].appPathToPlugin);
|
||||
|
||||
// Either use the tsconfig file from the generated app or the one inside the .cache folder
|
||||
// so we can develop plugins in TS while being in a JS app
|
||||
const tsConfigFilePath = useTypeScript
|
||||
? path.join(appDir, 'src', 'admin', 'tsconfig.json')
|
||||
: path.resolve(entry, 'tsconfig.json');
|
||||
|
||||
const config = getCustomWebpackConfig(appDir, {
|
||||
appDir,
|
||||
cacheDir,
|
||||
@ -53,7 +57,7 @@ async function build({
|
||||
options,
|
||||
pluginsPath,
|
||||
roots,
|
||||
useTypeScript,
|
||||
tsConfigFilePath,
|
||||
});
|
||||
|
||||
const compiler = webpack(config);
|
||||
@ -94,19 +98,14 @@ async function clean({ appDir, buildDestDir }) {
|
||||
fs.removeSync(cacheDir);
|
||||
}
|
||||
|
||||
async function watchAdmin({
|
||||
appDir,
|
||||
browser,
|
||||
buildDestDir,
|
||||
host,
|
||||
options,
|
||||
plugins,
|
||||
port,
|
||||
useTypeScript,
|
||||
}) {
|
||||
async function watchAdmin({ appDir, browser, buildDestDir, host, options, plugins, port }) {
|
||||
const useTypeScript = await isTypeScriptProject(
|
||||
path.join(appDir, 'src', 'admin'),
|
||||
'tsconfig.json'
|
||||
);
|
||||
// Create the cache dir containing the front-end files.
|
||||
const cacheDir = path.join(appDir, '.cache');
|
||||
await createCacheDir({ appDir, plugins, useTypeScript });
|
||||
await createCacheDir({ appDir, plugins });
|
||||
|
||||
const entry = path.join(cacheDir, 'admin', 'src');
|
||||
const dest = path.join(buildDestDir, 'build');
|
||||
@ -120,6 +119,12 @@ async function watchAdmin({
|
||||
|
||||
const pluginsPath = Object.keys(plugins).map(pluginName => plugins[pluginName].appPathToPlugin);
|
||||
|
||||
// Either use the tsconfig file from the generated app or the one inside the .cache folder
|
||||
// so we can develop plugins in TS while being in a JS app
|
||||
const tsConfigFilePath = useTypeScript
|
||||
? path.join(appDir, 'src', 'admin', 'tsconfig.json')
|
||||
: path.resolve(entry, 'tsconfig.json');
|
||||
|
||||
const args = {
|
||||
appDir,
|
||||
cacheDir,
|
||||
@ -147,7 +152,7 @@ async function watchAdmin({
|
||||
disableDotRule: true,
|
||||
},
|
||||
},
|
||||
useTypeScript,
|
||||
tsConfigFilePath,
|
||||
};
|
||||
|
||||
const webpackConfig = getCustomWebpackConfig(appDir, args);
|
||||
|
||||
@ -53,6 +53,7 @@
|
||||
"@strapi/babel-plugin-switch-ee-ce": "4.1.7",
|
||||
"@strapi/design-system": "0.0.1-alpha.79",
|
||||
"@strapi/helper-plugin": "4.1.7",
|
||||
"@strapi/typescript-utils": "4.1.7",
|
||||
"@strapi/icons": "0.0.1-alpha.79",
|
||||
"@strapi/utils": "4.1.7",
|
||||
"axios": "0.24.0",
|
||||
|
||||
@ -22,6 +22,8 @@ const smp = new SpeedMeasurePlugin();
|
||||
const buildAdmin = async () => {
|
||||
const entry = path.join(__dirname, '..', 'admin', 'src');
|
||||
const dest = path.join(__dirname, '..', 'build');
|
||||
const tsConfigFilePath = path.join(__dirname, '..', 'admin', 'src', 'tsconfig.json');
|
||||
|
||||
const corePlugins = getCorePluginsPath();
|
||||
const plugins = getPluginToInstallPath(PLUGINS_TO_INSTALL);
|
||||
const allPlugins = { ...corePlugins, ...plugins };
|
||||
@ -40,6 +42,7 @@ const buildAdmin = async () => {
|
||||
backend: 'http://localhost:1337',
|
||||
adminPath: '/admin/',
|
||||
},
|
||||
tsConfigFilePath,
|
||||
};
|
||||
|
||||
const config =
|
||||
|
||||
@ -3,6 +3,7 @@
|
||||
const path = require('path');
|
||||
const _ = require('lodash');
|
||||
const fs = require('fs-extra');
|
||||
const { isTypeScriptProject } = require('@strapi/typescript-utils');
|
||||
const getCustomAppConfigFile = require('./get-custom-app-config-file');
|
||||
|
||||
const getPkgPath = name => path.dirname(require.resolve(`${name}/package.json`));
|
||||
@ -67,9 +68,14 @@ async function copyAdmin(dest) {
|
||||
await fs.copy(path.resolve(adminPath, 'package.json'), path.resolve(dest, 'package.json'));
|
||||
}
|
||||
|
||||
async function createCacheDir({ appDir, plugins, useTypeScript }) {
|
||||
async function createCacheDir({ appDir, plugins }) {
|
||||
const cacheDir = path.resolve(appDir, '.cache');
|
||||
|
||||
const useTypeScript = await isTypeScriptProject(
|
||||
path.join(appDir, 'src', 'admin'),
|
||||
'tsconfig.json'
|
||||
);
|
||||
|
||||
const pluginsWithFront = Object.keys(plugins)
|
||||
.filter(pluginName => {
|
||||
const pluginInfo = plugins[pluginName];
|
||||
@ -115,6 +121,44 @@ async function createCacheDir({ appDir, plugins, useTypeScript }) {
|
||||
|
||||
// create plugins.js with plugins requires
|
||||
await createPluginsJs(pluginsWithFront, cacheDir);
|
||||
|
||||
// create the tsconfig.json file so we can develop plugins in ts while being in a JS project
|
||||
if (!useTypeScript) {
|
||||
await createTSConfigFile(cacheDir);
|
||||
}
|
||||
}
|
||||
|
||||
async function createTSConfigFile(dest) {
|
||||
const tsConfig = {
|
||||
compilerOptions: {
|
||||
lib: ['es2019', 'es2020.promise', 'es2020.bigint', 'es2020.string', 'DOM'],
|
||||
noImplicitAny: false,
|
||||
module: 'es2020',
|
||||
target: 'es5',
|
||||
jsx: 'react',
|
||||
allowJs: true,
|
||||
strict: true,
|
||||
moduleResolution: 'node',
|
||||
skipLibCheck: true,
|
||||
esModuleInterop: true,
|
||||
allowSyntheticDefaultImports: true,
|
||||
resolveJsonModule: true,
|
||||
noEmit: false,
|
||||
incremental: true,
|
||||
},
|
||||
include: ['../../../src/admin/src/*', '../../../src/**/**/admin/src/*'],
|
||||
exclude: ['node_modules', '**/*.test.js', '*.js'],
|
||||
};
|
||||
|
||||
const filePath = path.join(dest, 'admin', 'src', 'tsconfig.json');
|
||||
|
||||
try {
|
||||
await fs.ensureFile(filePath);
|
||||
|
||||
await fs.writeJSON(filePath, tsConfig, { spaces: 2 });
|
||||
} catch (err) {
|
||||
console.log(err);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = createCacheDir;
|
||||
|
||||
@ -2,15 +2,17 @@
|
||||
|
||||
const { join } = require('path');
|
||||
const fse = require('fs-extra');
|
||||
const { isTypeScriptProject } = require('@strapi/typescript-utils');
|
||||
|
||||
/**
|
||||
* Retrieve the custom admin entry file name
|
||||
* @param {String} dir - Directory of the admin panel
|
||||
* @param {Boolean} useTypeScript - Does the custom admin entry file use TS
|
||||
* @returns String
|
||||
*/
|
||||
const getCustomAppConfigFile = async (dir, useTypeScript) => {
|
||||
const getCustomAppConfigFile = async dir => {
|
||||
const adminSrcPath = join(dir, 'src', 'admin');
|
||||
const useTypeScript = await isTypeScriptProject(adminSrcPath, 'tsconfig.json');
|
||||
|
||||
const files = await fse.readdir(adminSrcPath);
|
||||
|
||||
const appRegex = new RegExp(`app.${useTypeScript ? 't' : 'j'}sx?$`);
|
||||
|
||||
@ -30,10 +30,10 @@ const hasNonDefaultPlugins = plugins => {
|
||||
return diff.length > 0;
|
||||
};
|
||||
|
||||
const hasCustomAdminCode = async (dir, useTypeScript) => {
|
||||
const hasCustomAdminCode = async dir => {
|
||||
const customAdminPath = path.join(dir, 'src', 'admin');
|
||||
|
||||
const customAdminAppConfigFile = await getCustomAppConfigFile(dir, useTypeScript);
|
||||
const customAdminAppConfigFile = await getCustomAppConfigFile(dir);
|
||||
const customAdminWebpackFile = path.join(customAdminPath, 'webpack.config.js');
|
||||
|
||||
const hasCustomConfigFile = !!customAdminAppConfigFile;
|
||||
@ -42,8 +42,8 @@ const hasCustomAdminCode = async (dir, useTypeScript) => {
|
||||
return hasCustomConfigFile || hasCustomWebpackFile;
|
||||
};
|
||||
|
||||
const shouldBuildAdmin = async ({ appDir, plugins, useTypeScript }) => {
|
||||
const appHasCustomAdminCode = await hasCustomAdminCode(appDir, useTypeScript);
|
||||
const shouldBuildAdmin = async ({ appDir, plugins }) => {
|
||||
const appHasCustomAdminCode = await hasCustomAdminCode(appDir);
|
||||
const appHasNonDefaultPlugins = hasNonDefaultPlugins(plugins);
|
||||
|
||||
return appHasCustomAdminCode || appHasNonDefaultPlugins;
|
||||
|
||||
@ -3,13 +3,16 @@
|
||||
const path = require('path');
|
||||
const fs = require('fs-extra');
|
||||
const chokidar = require('chokidar');
|
||||
const { isTypeScriptProject } = require('@strapi/typescript-utils');
|
||||
|
||||
/**
|
||||
* Listen to files change and copy the changed files in the .cache/admin folder
|
||||
* when using the dev mode
|
||||
* @param {string} dir
|
||||
*/
|
||||
async function watchAdminFiles(dir, useTypeScript) {
|
||||
async function watchAdminFiles(dir) {
|
||||
const useTypeScript = await isTypeScriptProject(path.join(dir, 'src', 'admin'), 'tsconfig.json');
|
||||
|
||||
const cacheDir = path.join(dir, '.cache');
|
||||
const targetExtensionFile = useTypeScript ? 'app.tsx' : 'app.js';
|
||||
const appExtensionFile = path.join(dir, 'src', 'admin', targetExtensionFile);
|
||||
|
||||
@ -28,6 +28,7 @@ module.exports = () => {
|
||||
dest,
|
||||
env,
|
||||
options,
|
||||
tsConfigFilePath: path.resolve(__dirname, 'admin', 'src', 'tsconfig.json'),
|
||||
};
|
||||
|
||||
const config = webpackConfig(args);
|
||||
|
||||
@ -13,7 +13,6 @@ const alias = require('./webpack.alias');
|
||||
const getClientEnvironment = require('./env');
|
||||
|
||||
module.exports = ({
|
||||
appDir,
|
||||
cacheDir,
|
||||
dest,
|
||||
entry,
|
||||
@ -29,7 +28,7 @@ module.exports = ({
|
||||
eeRoot: './ee/admin',
|
||||
ceRoot: './admin/src',
|
||||
},
|
||||
useTypeScript,
|
||||
tsConfigFilePath,
|
||||
}) => {
|
||||
const isProduction = env === 'production';
|
||||
|
||||
@ -50,34 +49,14 @@ module.exports = ({
|
||||
]
|
||||
: [];
|
||||
|
||||
if (useTypeScript) {
|
||||
const tsChecker = new ForkTsCheckerPlugin({
|
||||
typescript: {
|
||||
// FIXME
|
||||
configFile: path.join(appDir, 'tsconfig-admin.json'),
|
||||
},
|
||||
});
|
||||
const tsChecker = new ForkTsCheckerPlugin({
|
||||
typescript: {
|
||||
// FIXME
|
||||
configFile: tsConfigFilePath,
|
||||
},
|
||||
});
|
||||
|
||||
webpackPlugins.push(tsChecker);
|
||||
}
|
||||
|
||||
const rules = [];
|
||||
|
||||
// webpack is quite slow to compile so it is best not to use the ts loader when
|
||||
// it is not needed in javascript apps.
|
||||
// Users can still add it by using the custom webpack config.
|
||||
if (useTypeScript) {
|
||||
rules.push({
|
||||
test: /\.tsx?$/,
|
||||
loader: require.resolve('esbuild-loader'),
|
||||
include: [cacheDir, ...pluginsPath],
|
||||
exclude: /node_modules/,
|
||||
options: {
|
||||
loader: 'tsx',
|
||||
target: 'es2015',
|
||||
},
|
||||
});
|
||||
}
|
||||
webpackPlugins.push(tsChecker);
|
||||
|
||||
// Directly inject a polyfill in the webpack entry point before the entry point
|
||||
// FIXME: I have noticed a bug regarding the helper-plugin and esbuild-loader
|
||||
@ -112,6 +91,16 @@ module.exports = ({
|
||||
},
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.tsx?$/,
|
||||
loader: require.resolve('esbuild-loader'),
|
||||
include: [cacheDir, ...pluginsPath],
|
||||
exclude: /node_modules/,
|
||||
options: {
|
||||
loader: 'tsx',
|
||||
target: 'es2015',
|
||||
},
|
||||
},
|
||||
{
|
||||
test: /\.m?js$/,
|
||||
include: cacheDir,
|
||||
@ -222,7 +211,6 @@ module.exports = ({
|
||||
},
|
||||
},
|
||||
},
|
||||
...rules,
|
||||
],
|
||||
},
|
||||
resolve: {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user