feat(cli): init module federation of build script

This commit is contained in:
Sam Tolmay 2020-10-26 18:42:43 +02:00
parent 519e604771
commit 34dba01724
6 changed files with 121 additions and 6 deletions

View File

@ -1,5 +1,6 @@
const path = require('path');
const { dependencies, devDependencies } = require('./package.json');
const { ModuleFederationPlugin } = require('webpack').container;
const { dependencies } = require('./package.json');
module.exports = {
entry: './src/index.js',
@ -11,7 +12,7 @@ module.exports = {
mode: 'production',
target: 'node',
node: false,
externals: Object.keys({ ...dependencies, ...devDependencies }),
externals: ['fs', 'path', 'fsevents'],
module: {
rules: [
{
@ -35,4 +36,15 @@ module.exports = {
},
],
},
plugins: [
new ModuleFederationPlugin({
name: 'build',
library: { type: 'commonjs' },
filename: 'remoteEntry.js',
exposes: {
'./build': './src/index.js',
},
shared: dependencies,
}),
],
};

View File

@ -15,10 +15,10 @@
*/
import path from 'path';
import buildScript from '@lowdefy/build';
import createPrint from '../../utils/print';
import getBuildScript from './getBuildScript';
import getLowdefyVersion from '../../utils/getLowdefyVersion';
import errorBoundary from '../../utils/errorBoundary';
import createPrint from '../../utils/print';
async function build(program) {
let baseDirectory = process.cwd();
@ -26,7 +26,7 @@ async function build(program) {
baseDirectory = path.resolve(program.baseDirectory);
}
const version = await getLowdefyVersion(program.baseDirectory);
console.log(version);
const buildScript = await getBuildScript(version);
buildScript({
logger: createPrint({ timestamp: true }),

View File

@ -0,0 +1,32 @@
/*
Copyright 2020 Lowdefy, Inc
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
import fs from 'fs';
import path from 'path';
import loadModule from '../../utils/loadModule';
async function getBuildScript(version) {
let buildScript;
const cleanVersion = version.replace(/[-.]/g, '_');
const cachePath = path.resolve(process.cwd(), `./.lowdefy/.cache/build/v${cleanVersion}`);
if (fs.existsSync(cachePath)) {
buildScript = await loadModule(cachePath, './build');
return buildScript.default;
}
return null;
}
export default getBuildScript;

View File

@ -1,3 +1,19 @@
/*
Copyright 2020 Lowdefy, Inc
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
import path from 'path';
import { readFile } from '@lowdefy/node-utils';
import getLowdefyVersion from './getLowdefyVersion';

View File

@ -0,0 +1,45 @@
/*
Copyright 2020 Lowdefy, Inc
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
import path from 'path';
async function loadModule(dir, moduleName, remoteEntry = 'remoteEntry.js') {
const importRemote = async (remoteEntryFile) => {
if (__webpack_share_scopes__.default) {
await __webpack_init_sharing__('default');
}
return new Promise((remoteResolve) => {
const container = __non_webpack_require__(remoteEntryFile);
const initContainer = new Promise((containerResolve) => {
if (__webpack_share_scopes__.default) {
containerResolve(container.init(__webpack_share_scopes__.default));
} else {
containerResolve();
}
});
initContainer.then(() => {
remoteResolve(container);
});
});
};
const container = await importRemote(path.resolve(`${dir}/${remoteEntry}`));
return container.get(moduleName).then((factory) => factory());
}
export default loadModule;

View File

@ -1,5 +1,6 @@
const path = require('path');
const webpack = require('webpack');
const { ModuleFederationPlugin } = require('webpack').container;
const { dependencies, devDependencies } = require('./package.json');
module.exports = {
@ -36,5 +37,14 @@ module.exports = {
},
],
},
plugins: [new webpack.BannerPlugin({ banner: '#!/usr/bin/env node', raw: true })],
plugins: [
new webpack.BannerPlugin({ banner: '#!/usr/bin/env node', raw: true }),
new ModuleFederationPlugin({
name: 'cli',
filename: 'remoteEntry.js',
remotes: {},
exposes: {},
shared: dependencies,
}),
],
};