Update build configurations structure and improve DX

This commit is contained in:
Aurelsicoko 2017-11-11 17:22:18 +01:00
parent aeb43d925c
commit d67c64a82a
9 changed files with 118 additions and 111 deletions

View File

@ -9,24 +9,41 @@ const webpack = require('webpack');
const pkg = require(path.resolve(process.cwd(), 'package.json'));
const pluginId = pkg.name.replace(/^strapi-/i, '');
const isAdmin = process.env.IS_ADMIN === 'true';
const appPath = isAdmin ? path.resolve(process.env.PWD, '..'): path.resolve(process.env.PWD, '..', '..');
try {
// Load app' configurations to update `plugins.json` automatically.
const strapi = require(path.join(appPath, 'node_modules', 'strapi'));
strapi.config.appPath = appPath;
strapi.log.level = 'silent';
(async () => {
await strapi.load();
})();
} catch (e) {
throw new Error(`You need to start the WebPack server from the /admin or /plugins/**/admin directories in a Strapi's project.`);
}
// Define remote and backend URLs.
const URLs = {
remote: null,
host: null,
backend: null
};
if (process.env.IS_ADMIN === 'true') {
if (isAdmin) {
// Load server configuration.
const serverConfig = path.resolve(process.env.PWD, '..', 'config', 'environments', _.lowerCase(process.env.NODE_ENV), 'server.json');
try {
const server = require(serverConfig);
const folder = _.get(server, 'admin.folder') ? server.admin.folder : '/admin';
const path = _.get(server, 'admin.path', '/admin');
if (process.env.PWD.indexOf(folder) !== -1) {
URLs.remote = _.get(server, 'admin.remoteURL', null) ? _.get(server, 'admin.remoteURL', null) : `http://${_.get(server, 'host', 'localhost')}:${_.get(server, 'port', 1337)}${folder}`;
URLs.backend = _.get(server, 'admin.backendURL', null) ? _.get(server, 'admin.backendURL', null) : `http://${_.get(server, 'host', 'localhost')}:${_.get(server, 'port', 1337)}`;
if (process.env.PWD.indexOf('/admin') !== -1) {
URLs.host = _.get(server, 'admin.build.host', `http://${_.get(server, 'host', 'localhost')}:${_.get(server, 'port', 1337)}${path}`);
URLs.backend = _.get(server, 'admin.build.backend', `http://${_.get(server, 'host', 'localhost')}:${_.get(server, 'port', 1337)}`);
}
} catch (e) {
throw new Error(`Impossible to access to ${serverConfig}`)
@ -44,18 +61,12 @@ if (process.env.npm_lifecycle_event === 'start') {
try {
fs.accessSync(path.resolve(process.env.PWD, '..', 'plugins'), fs.constants.R_OK);
} catch (e) {
try {
fs.accessSync(path.resolve(process.env.PWD, '..', 'api'), fs.constants.R_OK);
// Allow app without plugins.
plugins.exist = true;
} catch (e) {
throw new Error(`You need to start the WebPack server from the /admin directory in a Strapi's project.`);
}
// Allow app without plugins.
plugins.exist = true;
}
// Read `plugins` directory.
plugins.src = process.env.IS_ADMIN === 'true' && !plugins.exist ? fs.readdirSync(path.resolve(process.env.PWD, '..', 'plugins')).filter(x => x[0] !== '.') : [];
plugins.src = isAdmin && !plugins.exist ? fs.readdirSync(path.resolve(process.env.PWD, '..', 'plugins')).filter(x => x[0] !== '.') : [];
// Construct object of plugin' paths.
plugins.folders = plugins.src.reduce((acc, current) => {
@ -189,7 +200,7 @@ module.exports = (options) => ({
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: JSON.stringify(process.env.NODE_ENV),
REMOTE_URL: JSON.stringify(URLs.remote),
REMOTE_URL: JSON.stringify(URLs.host),
BACKEND_URL: JSON.stringify(URLs.backend),
},
}),

View File

@ -14,28 +14,24 @@ const postcssReporter = require('postcss-reporter');
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
const LodashModuleReplacementPlugin = require('lodash-webpack-plugin');
let noPlugin = false;
let plugins = [];
let pluginFolders = {};
// Load plugins into the same build in development mode.
const plugins = {
exist: false,
src: [],
folders: {}
};
if (process.env.npm_lifecycle_event === 'start') {
try {
fs.accessSync(path.resolve(process.env.PWD, '..', 'plugins'), fs.constants.R_OK);
} catch (e) {
try {
fs.accessSync(path.resolve(process.env.PWD, '..', 'api'), fs.constants.R_OK);
// Allow app without plugins.
noPlugin = true;
} catch (e) {
throw new Error(`You need to start the WebPack server from the /admin directory in a Strapi's project.`);
}
// Allow app without plugins.
plugins.exist = true;
}
plugins = process.env.IS_ADMIN === 'true' && !noPlugin ? fs.readdirSync(path.resolve(process.env.PWD, '..', 'plugins'))
.filter(x => x[0] !== '.') : [];
plugins.src = process.env.IS_ADMIN === 'true' && !plugins.exist ? fs.readdirSync(path.resolve(process.env.PWD, '..', 'plugins')).filter(x => x[0] !== '.') : [];
pluginFolders = plugins.reduce((acc, current) => {
plugins.folders = plugins.reduce((acc, current) => {
acc[current] = path.resolve(process.env.PWD, '..', 'plugins', current, 'node_modules', 'strapi-helper-plugin', 'lib', 'src');
return acc;
@ -52,8 +48,8 @@ module.exports = require('./webpack.base.babel')({
`webpack-hot-middleware/client?path=http://localhost:${port}/__webpack_hmr`,
appPath,
]
}, plugins.reduce((acc, current) => {
acc[current] = path.resolve(pluginFolders[current], 'app.js');
}, plugins.src.reduce((acc, current) => {
acc[current] = path.resolve(plugins.folders[current], 'app.js');
return acc;
}, {})

View File

@ -46,25 +46,26 @@ const plugins = [
// new BundleAnalyzerPlugin(),
];
let folder = 'admin';
let remoteURL = undefined;
// Load server configuration.
const serverConfig = isAdmin ?
path.resolve(process.env.PWD, '..', 'config', 'environments', _.lowerCase(process.env.NODE_ENV), 'server.json'):
path.resolve(process.env.PWD, '..', '..', 'config', 'environments', _.lowerCase(process.env.NODE_ENV), 'server.json');
const server = require(serverConfig);
const settings = {
path: 'admin',
folder: 'plugins',
host: _.get(server, 'admin.build.host')
};
// Build the `index.html file`
if (isAdmin) {
// Load server configuration.
const serverConfig = path.resolve(process.env.PWD, '..', 'config', 'environments', _.lowerCase(process.env.NODE_ENV), 'server.json');
const server = require(serverConfig);
settings.path = _.get(server, 'admin.path', 'admin');
settings.folder = _.get(server, 'admin.build.plugins.folder', 'plugins');
if (_.get(server, 'admin.remoteURL')) {
remoteURL = server.admin.remoteURL;
}
folder = _.get(server, 'admin.folder') ?
server.admin.folder :
'admin';
if (folder[0] === '/') {
folder = folder.substring(1);
if (settings.path[0] === '/') {
settings.path = settings.path.substring(1);
}
plugins.push(new HtmlWebpackPlugin({
@ -103,14 +104,16 @@ const appPath = isAdmin
const publicPath = (() => {
if (isAdmin) {
if (remoteURL) {
return `${remoteURL}/`;
if (settings.host) {
return `${settings.host}/`;
}
return `/${folder}/`;
return `/${settings.path}/`;
}
return `/${pluginId}/assets/`;
return settings.host ?
`${settings.host}/${settings.folder}/${pluginId}/`:
`/${settings.folder}/${pluginId}/`;
})();
module.exports = require('./webpack.base.babel')({

View File

@ -8,7 +8,9 @@ module.exports = function() {
return Promise.all([
new Promise((resolve, reject) => {
// Load configurations.
glob('./api/*/!(config)/*.*(js|json)', {}, (err, files) => {
glob('./api/*/!(config)/*.*(js|json)', {
cwd: this.config.appPath
}, (err, files) => {
if (err) {
return reject(err);
}
@ -20,7 +22,9 @@ module.exports = function() {
}),
new Promise((resolve, reject) => {
// Load configurations.
glob('./admin/!(config|node_modules)/*.*(js|json)', {}, (err, files) => {
glob('./admin/!(config|node_modules)/*.*(js|json)', {
cwd: this.config.appPath
}, (err, files) => {
if (err) {
return reject(err);
}
@ -32,7 +36,9 @@ module.exports = function() {
}),
new Promise((resolve, reject) => {
// Load configurations.
glob('./plugins/*/!(config|node_modules)/*.*(js|json)', {}, (err, files) => {
glob('./plugins/*/!(config|node_modules)/*.*(js|json)', {
cwd: this.config.appPath
}, (err, files) => {
if (err) {
return reject(err);
}

View File

@ -10,7 +10,9 @@ module.exports.nested = function() {
return Promise.all([
// Load root configurations.
new Promise((resolve, reject) => {
glob('./config/**/*.*(js|json)', {}, (err, files) => {
glob('./config/**/*.*(js|json)', {
cwd: this.config.appPath
}, (err, files) => {
if (err) {
return reject(err);
}
@ -20,7 +22,9 @@ module.exports.nested = function() {
}),
// Load APIs configurations.
new Promise((resolve, reject) => {
glob('./api/*/config/**/*.*(js|json)', {}, (err, files) => {
glob('./api/*/config/**/*.*(js|json)', {
cwd: this.config.appPath
}, (err, files) => {
if (err) {
return reject(err);
}
@ -30,7 +34,9 @@ module.exports.nested = function() {
}),
// Load plugins configurations.
new Promise((resolve, reject) => {
glob('./plugins/*/config/**/*.*(js|json)', {}, (err, files) => {
glob('./plugins/*/config/**/*.*(js|json)', {
cwd: this.config.appPath
}, (err, files) => {
if (err) {
return reject(err);
}
@ -40,7 +46,9 @@ module.exports.nested = function() {
}),
// Load admin configurations.
new Promise((resolve, reject) => {
glob('./admin/config/**/*.*(js|json)', {}, (err, files) => {
glob('./admin/config/**/*.*(js|json)', {
cwd: this.config.appPath
}, (err, files) => {
if (err) {
return reject(err);
}

View File

@ -38,7 +38,7 @@ module.exports = function() {
// Load configurations.
glob('./*', {
cwd: path.resolve(process.cwd(), 'hooks')
cwd: path.resolve(this.config.appPath, 'hooks')
}, (err, files) => {
if (err) {
return reject(err);

View File

@ -30,7 +30,7 @@ module.exports = function() {
);
}),
new Promise((resolve, reject) => {
const cwd = process.cwd();
const cwd = this.config.appPath;
glob(
'./node_modules/*(koa-*|kcors)',
@ -47,7 +47,7 @@ module.exports = function() {
);
}),
new Promise((resolve, reject) => {
const cwd = process.cwd();
const cwd = this.config.appPath;
glob(
'./node_modules/*(strapi-middleware-*)',
@ -81,7 +81,7 @@ module.exports = function() {
);
}),
new Promise((resolve, reject) => {
const cwd = path.resolve(process.cwd(), 'middlewares');
const cwd = path.resolve(this.config.appPath, 'middlewares');
glob(
'./*',

View File

@ -7,35 +7,27 @@ const fs = require('fs');
module.exports = function() {
return new Promise((resolve, reject) => {
const folder = (() => {
if (_.get(strapi.config.currentEnvironment.server, 'admin.folder')) {
// Relative URL
if (strapi.config.currentEnvironment.server.admin.folder[0] === '/') {
return strapi.config.currentEnvironment.server.admin.folder.substring(1);
}
return strapi.config.currentEnvironment.server.admin.folder;
}
return 'admin';
})();
const folder = ((url = _.get(strapi.config.currentEnvironment.server, 'admin.path', 'admin')) =>
url[0] === '/' ? url.substring(1) : url
)();
const configuratePlugin = (acc, current, source, x) => {
switch (source) {
case 'remote':
if (!_.get(this.config.environments[current].server, 'admin.remoteURL')) {
throw new Error(`You can't use \`remote\` as a source without set the \`remoteURL\` configuration.`);
case 'host': {
if (!_.get(this.config.environments[current].server, 'admin.build.host')) {
throw new Error(`You can't use \`remote\` as a source without set the \`host\` configuration.`);
}
const subFolder = _.get(this.config.environments[current].server, 'admin.plugins.subFolder', null);
const folder = _.get(this.config.environments[current].server, 'admin.build.plugins.folder', null);
if (_.isString(subFolder)) {
const cleanSubFolder = subFolder[0] === '/' ? subFolder.substring(1) : subFolder;
if (_.isString(folder)) {
const cleanFolder = folder[0] === '/' ? folder.substring(1) : folder;
return `${this.config.environments[current].server.admin.remoteURL}/${cleanSubFolder}/${x}/main.js`;
return `${this.config.environments[current].server.admin.build.host}/${cleanFolder}/${x}/main.js`;
}
return `${this.config.environments[current].server.admin.remoteURL}/${x}/main.js`;
return `${this.config.environments[current].server.admin.build.host}/${x}/main.js`;
}
case 'custom':
if (!_.isEmpty(_.get(this.plugins[x].config, `sources.${current}`, {}))) {
return acc[current] = this.plugins[x].config.sources[current];
@ -49,14 +41,14 @@ module.exports = function() {
};
const sourcePath = process.env.NODE_ENV !== 'test' ?
path.resolve(this.config.appPath, folder, 'admin', 'src', 'config', 'plugins.json'):
path.resolve(this.config.appPath, 'admin', 'admin', 'src', 'config', 'plugins.json'):
path.resolve(this.config.appPath, 'packages', 'strapi-admin', 'admin', 'src', 'config', 'plugins.json');
const buildPath = process.env.NODE_ENV !== 'test' ?
path.resolve(this.config.appPath, folder, 'admin', 'build', 'config', 'plugins.json'):
path.resolve(this.config.appPath, 'admin', 'admin', 'build', 'config', 'plugins.json'):
path.resolve(this.config.appPath, 'packages', 'strapi-admin', 'admin', 'build', 'config', 'plugins.json');
try {
fs.access(path.resolve(this.config.appPath, folder, 'admin'), err => {
fs.access(path.resolve(this.config.appPath, 'admin', 'admin'), err => {
if (err && err.code !== 'ENOENT') {
return reject(err);
}
@ -96,7 +88,7 @@ module.exports = function() {
const data = Object.keys(this.plugins).map(x => ({
id: x,
source: Object.keys(this.config.environments).reduce((acc, current) => {
const source = _.get(this.config.environments[current].server, 'admin.plugins.source', 'origin');
const source = _.get(this.config.environments[current].server, 'admin.build.plugins.source', 'origin');
if (_.isString(source)) {
acc[current] = configuratePlugin(acc, current, source, x);

View File

@ -72,8 +72,8 @@ module.exports = strapi => {
]
});
const basename = _.get(strapi.config.currentEnvironment.server, 'admin.folder') ?
strapi.config.currentEnvironment.server.admin.folder :
const basename = _.get(strapi.config.currentEnvironment.server, 'admin.path') ?
strapi.config.currentEnvironment.server.admin.path :
'/admin';
// Serve /admin index page.
@ -86,7 +86,7 @@ module.exports = strapi => {
await next();
},
strapi.koaMiddlewares.static(`.${basename}/admin/build`, {
strapi.koaMiddlewares.static(`./admin/admin/build`, {
maxage: strapi.config.middleware.settings.public.maxAge,
defer: true
})
@ -103,7 +103,7 @@ module.exports = strapi => {
await next();
},
strapi.koaMiddlewares.static(`.${basename}/admin/build`, {
strapi.koaMiddlewares.static(`./admin/admin/build`, {
maxage: strapi.config.middleware.settings.public.maxAge,
defer: true
})
@ -125,7 +125,7 @@ module.exports = strapi => {
}
// Handle subfolders.
return await strapi.koaMiddlewares.static(`.${basename}/admin/build/${ctx.params.resource}`, {
return await strapi.koaMiddlewares.static(`./admin/admin/build/${ctx.params.resource}`, {
maxage: strapi.config.middleware.settings.public.maxAge,
defer: true
})(ctx, next);
@ -142,7 +142,7 @@ module.exports = strapi => {
await next();
},
strapi.koaMiddlewares.static(`.${basename}/admin/build`, {
strapi.koaMiddlewares.static(`./admin/admin/build`, {
maxage: strapi.config.middleware.settings.public.maxAge,
defer: true
})
@ -158,28 +158,19 @@ module.exports = strapi => {
async (ctx, next) => {
ctx.url = path.basename(ctx.url);
await next();
// Try to find assets into the build first.
return await strapi.koaMiddlewares.static(`./plugins/${plugin}/admin/build`, {
maxage: strapi.config.middleware.settings.public.maxAge,
defer: true
})(ctx, next);
},
strapi.koaMiddlewares.static(`./plugins/${plugin}/${strapi.config.middleware.settings.public.path || strapi.config.paths.static}`, {
maxage: strapi.config.middleware.settings.public.maxAge,
defer: true
})
]
});
strapi.router.route({
method: 'GET',
path: `/${plugin}/assets/*.*`,
handler: [
async (ctx, next) => {
ctx.url = path.basename(ctx.url);
await next();
// Try to find assets in the source then.
return await strapi.koaMiddlewares.static(`./plugins/${plugin}/${strapi.config.middleware.settings.public.path || strapi.config.paths.static}`, {
maxage: strapi.config.middleware.settings.public.maxAge,
defer: true
})(ctx, next);
},
strapi.koaMiddlewares.static(`./plugins/${plugin}/admin/build`, {
maxage: strapi.config.middleware.settings.public.maxAge,
defer: true
})
]
});
});