Avoid to rebuild on path change and override build configuration

This commit is contained in:
Aurelsicoko 2017-11-11 22:14:05 +01:00
parent d67c64a82a
commit d0c3f7f8b5
17 changed files with 161 additions and 38 deletions

View File

@ -4,6 +4,17 @@
* This is the entry file for the application, only setup and boilerplate
* code.
*/
/* eslint-disable */
// Retrieve remote and backend URLs.
const remoteURL = process.env.REMOTE_URL || 'http://localhost:1337/admin';
const backendURL = process.env.BACKEND_URL || 'http://localhost:1337';
// Retrieve development URL to avoid to re-build.
const devFrontURL = document.getElementsByTagName('body')[0].getAttribute('front');
const devBackendURL = document.getElementsByTagName('body')[0].getAttribute('back');
import './public-path';
import 'babel-polyfill';
// Import all the third party stuff
@ -24,15 +35,12 @@ import { pluginLoaded, updatePlugin } from 'containers/App/actions';
import configureStore from './store';
import { translationMessages, languages } from './i18n';
// Retrieve remote and backend URLs.
const remoteURL = process.env.REMOTE_URL || 'http://localhost:1337/admin';
const backendURL = process.env.BACKEND_URL || 'http://localhost:1337';
/* eslint-enable */
// Create redux store with history
const initialState = {};
const history = createHistory({
basename: remoteURL.replace(window.location.origin, ''),
basename: (devFrontURL || remoteURL).replace(window.location.origin, ''),
});
const store = configureStore(initialState, history);
@ -49,7 +57,6 @@ const render = (translatedMessages) => {
);
};
// Hot reloadable translation json files
if (module.hot) {
// modules.hot.accept does not accept dynamic dependencies,
@ -74,7 +81,7 @@ window.onload = function onLoad() {
// Don't inject plugins in development mode.
if (window.location.port !== '4000') {
fetch(`${remoteURL}/config/plugins.json`)
fetch(`${devFrontURL || remoteURL}/config/plugins.json`)
.then(response => {
return response.json();
})
@ -140,9 +147,9 @@ const displayNotification = (message, status) => {
store.dispatch(showNotification(message, status));
};
window.strapi = {
remoteURL,
backendURL,
window.strapi = Object.assign(window.strapi || {}, {
remoteURL: devFrontURL || remoteURL,
backendURL: devBackendURL || backendURL,
registerPlugin,
notification: {
success: (message) => {
@ -168,7 +175,7 @@ window.strapi = {
}),
router: history,
languages,
};
});
const dispatch = store.dispatch;
export {

View File

@ -0,0 +1,5 @@
// Retrieve URLs.
const remoteURL = process.env.REMOTE_URL || 'http://localhost:1337/admin';
const devURL = document.getElementsByTagName('body')[0].getAttribute('front');
__webpack_public_path__ = `${(devURL || remoteURL).replace(window.location.origin, '')}/`;

View File

@ -30,6 +30,7 @@ module.exports = scope => {
'preanalyze': 'npm run analyze:clean',
'analyze': 'node node_modules/strapi-helper-plugin/lib/internals/scripts/analyze.js',
'prebuild': 'npm run build:clean && npm run test',
'build:dev': 'cross-env NODE_ENV=development webpack --config node_modules/strapi-helper-plugin/lib/internals/webpack/webpack.prod.babel.js --color -p --progress',
'build': 'cross-env NODE_ENV=production webpack --config node_modules/strapi-helper-plugin/lib/internals/webpack/webpack.prod.babel.js --color -p --progress',
'build:clean': 'rimraf admin/build',
'start': 'cross-env NODE_ENV=development node node_modules/strapi-helper-plugin/lib/server',

View File

@ -11,7 +11,7 @@ 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, '..', '..');
const appPath = isAdmin ? path.resolve(process.env.PWD, '..') : path.resolve(process.env.PWD, '..', '..');
try {
// Load app' configurations to update `plugins.json` automatically.
@ -24,6 +24,7 @@ try {
await strapi.load();
})();
} catch (e) {
console.log(e);
throw new Error(`You need to start the WebPack server from the /admin or /plugins/**/admin directories in a Strapi's project.`);
}
@ -79,8 +80,7 @@ if (process.env.npm_lifecycle_event === 'start') {
module.exports = (options) => ({
entry: options.entry,
output: Object.assign({ // Compile into js/build.js
path: path.join(process.cwd(), 'admin', 'build'),
publicPath: '/',
path: path.join(process.cwd(), 'admin', 'build')
}, options.output), // Merge with env dependent settings
module: {
loaders: [{

View File

@ -119,14 +119,13 @@ const publicPath = (() => {
module.exports = require('./webpack.base.babel')({
// In production, we skip all hot-reloading stuff
entry: {
main: appPath
main: appPath,
},
// Utilize long-term caching by adding content hashes (not compilation hashes) to compiled assets
output: {
filename: '[name].js',
chunkFilename: '[name].[chunkhash].chunk.js',
publicPath,
chunkFilename: '[name].[chunkhash].chunk.js'
},
// In production, we minify our CSS with cssnano

View File

@ -4,6 +4,7 @@
* This is the entry file for the application,
* only setup and plugin code.
*/
import './public-path.js'; // eslint-disabled-line
import React from 'react';
import { Provider } from 'react-redux';

View File

@ -0,0 +1,5 @@
const pluginPkg = require('../../../../package.json');
const pluginId = pluginPkg.name.replace(/^strapi-plugin-/i, '');
const publicPath = `plugins/${pluginId}/`;
__webpack_public_path__ = `${(strapi.remoteURL).replace(window.location.origin, '')}/${publicPath}`;

View File

@ -33,6 +33,7 @@
"preanalyze": "npm run analyze:clean",
"analyze": "node node_modules/strapi-helper-plugin/lib/internals/scripts/analyze.js",
"prebuild": "npm run build:clean && npm run test",
"build:dev": "cross-env NODE_ENV=development webpack --config node_modules/strapi-helper-plugin/lib/internals/webpack/webpack.prod.babel.js --color -p --progress",
"build": "cross-env NODE_ENV=production webpack --config node_modules/strapi-helper-plugin/lib/internals/webpack/webpack.prod.babel.js --color -p --progress",
"build:clean": "rimraf admin/build",
"start": "cross-env NODE_ENV=development PLUGIN=true node node_modules/strapi-helper-plugin/lib/server",

View File

@ -12,6 +12,7 @@
"preanalyze": "npm run analyze:clean",
"analyze": "node node_modules/strapi-helper-plugin/lib/internals/scripts/analyze.js",
"prebuild": "npm run build:clean && npm run test",
"build:dev": "cross-env NODE_ENV=development webpack --config node_modules/strapi-helper-plugin/lib/internals/webpack/webpack.prod.babel.js --color -p --progress",
"build": "cross-env NODE_ENV=production webpack --config node_modules/strapi-helper-plugin/lib/internals/webpack/webpack.prod.babel.js --color -p --progress",
"build:clean": "rimraf admin/build",
"start": "cross-env NODE_ENV=development node node_modules/strapi-helper-plugin/lib/server",

View File

@ -12,6 +12,7 @@
"preanalyze": "npm run analyze:clean",
"analyze": "node node_modules/strapi-helper-plugin/lib/internals/scripts/analyze.js",
"prebuild": "npm run build:clean && npm run test",
"build:dev": "cross-env NODE_ENV=development webpack --config node_modules/strapi-helper-plugin/lib/internals/webpack/webpack.prod.babel.js --color -p --progress",
"build": "cross-env NODE_ENV=production webpack --config node_modules/strapi-helper-plugin/lib/internals/webpack/webpack.prod.babel.js --color -p --progress",
"build:clean": "rimraf admin/build",
"start": "cross-env NODE_ENV=development node node_modules/strapi-helper-plugin/lib/server",

View File

@ -62,7 +62,14 @@ module.exports = function() {
const setFilesToWatch = (src) => {
var files = fs.readdirSync(src);
_.forEach(files, file => {
if (_.startsWith(file, '.') || file === 'node_modules' || file === 'plugins.json') return;
if (
_.startsWith(file, '.') ||
file === 'node_modules' ||
file === 'plugins.json' ||
file === 'index.html'
) {
return;
}
const filePath = `${src}/${file}`;
if (fs.statSync(filePath).isDirectory()) setFilesToWatch(filePath);

View File

@ -8,7 +8,7 @@ const path = require('path');
const cluster = require('cluster');
const { includes, get, assign } = require('lodash');
const { logger, models } = require('strapi-utils');
const { nestedConfigurations, appConfigurations, apis, middlewares, hooks, plugins } = require('./core');
const { nestedConfigurations, appConfigurations, apis, middlewares, hooks, plugins, admin } = require('./core');
const initializeMiddlewares = require('./middlewares');
const initializeHooks = require('./hooks');
const { EventEmitter } = require('events');
@ -95,6 +95,8 @@ class Strapi extends EventEmitter {
await this.bootstrap();
// Freeze object.
await this.freeze();
// Update source admin.
await admin.call(this);
// Launch server.
this.server.listen(this.config.port, err => {
if (err) {

View File

@ -0,0 +1,63 @@
'use strict';
// Dependencies.
const _ = require('lodash');
const path = require('path');
const fs = require('fs');
const cheerio = require('cheerio')
module.exports = function() {
return new Promise((resolve, reject) => {
try {
if (this.config.environment === 'test') {
return resolve();
}
const sourcePath = path.resolve(this.config.appPath, 'admin', 'admin', 'build', 'index.html');
fs.access(path.resolve(this.config.appPath, 'admin', 'admin'), err => {
if (err && err.code !== 'ENOENT') {
return reject(err);
}
// No admin.
if (err && err.code === 'ENOENT') {
return resolve();
}
// Try to access to path.
fs.access(sourcePath, err => {
if (err) {
return reject(err);
}
fs.readFile(sourcePath, (err, html) => {
const $ = cheerio.load(html.toString());
$('script').each(function(i, elem) {
if ($(this).attr('src')) {
const parse = path.parse($(this).attr('src'));
$(this).attr('src', `${_.get(strapi.config.currentEnvironment.server, 'admin.path', '/admin')}/${parse.base}`);
}
});
// Remove previous
$('body').attr('front', `http://${strapi.config.currentEnvironment.server.host}:${strapi.config.currentEnvironment.server.port}${_.get(strapi.config.currentEnvironment.server, 'admin.path', '/admin')}`);
$('body').attr('back', `http://${strapi.config.currentEnvironment.server.host}:${strapi.config.currentEnvironment.server.port}`);
fs.writeFile(sourcePath, $.html(), (err) => {
if (err) {
return reject(err);
}
resolve();
});
});
});
});
} catch (e) {
reject(e);
}
});
};

View File

@ -5,6 +5,7 @@ const apis = require('./apis');
const middlewares = require('./middlewares');
const hooks = require('./hooks');
const plugins = require('./plugins');
const admin = require('./admin');
module.exports = {
nestedConfigurations: nested,
@ -12,5 +13,6 @@ module.exports = {
apis,
middlewares,
hooks,
plugins
plugins,
admin
};

View File

@ -6,7 +6,7 @@ const { parallel } = require('async');
const { after, includes, indexOf, drop, dropRight, uniq, defaultsDeep, get, set, isEmpty, isUndefined, union, merge } = require('lodash');
module.exports = function() {
const accepted = Object.keys(this.plugins).map(url => `^\/${url}/`).concat(['^\/admin/']);
const accepted = Object.keys(this.plugins).map(url => `^\/${url}/`).concat([`^${get(this.config.currentEnvironment.server, 'admin.path', '/admin')}/`]);
// Set if is admin destination for middleware application.
// TODO: Use dynamic config for admin url.

View File

@ -110,6 +110,27 @@ module.exports = strapi => {
]
});
// Allow page refresh
strapi.router.route({
method: 'GET',
path: `${basename}/plugins/*`,
handler: [
async (ctx, next) => {
const parse = path.parse(ctx.url);
if (parse.ext === '') {
ctx.url = 'index.html';
}
await next();
},
strapi.koaMiddlewares.static(`./admin/admin/build`, {
maxage: strapi.config.middleware.settings.public.maxAge,
defer: true
})
]
});
// Serve plugins assets.
strapi.router.route({
method: 'GET',
@ -132,23 +153,6 @@ module.exports = strapi => {
}
});
// Allow page refresh
strapi.router.route({
method: 'GET',
path: `${basename}/plugins/*`,
handler: [
async (ctx, next) => {
ctx.url = 'index.html';
await next();
},
strapi.koaMiddlewares.static(`./admin/admin/build`, {
maxage: strapi.config.middleware.settings.public.maxAge,
defer: true
})
]
});
// Plugins.
_.forEach(strapi.plugins, (value, plugin) => {
strapi.router.route({
@ -173,6 +177,29 @@ module.exports = strapi => {
},
]
});
strapi.router.route({
method: 'GET',
path: `${basename}/plugins/${plugin}/*.*`,
handler: [
async (ctx, next) => {
ctx.url = path.basename(ctx.url);
// 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);
},
async (ctx, 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);
},
]
});
});
cb();

View File

@ -32,6 +32,7 @@
"dependencies": {
"async": "^2.1.2",
"boom": "^5.2.0",
"cheerio": "^1.0.0-rc.2",
"delegates": "^1.0.0",
"glob": "^7.1.2",
"kcors": "^2.2.0",