From c1ed102c10000713106c8f3c2743eebd3b55305b Mon Sep 17 00:00:00 2001 From: Jesse MacFadyen Date: Wed, 3 Feb 2021 15:42:12 -0800 Subject: [PATCH 1/7] re-added implementation, tests, and fixtures --- src/build-actions.js | 107 +++++++++++------- .../actions/actionname/action.js | 15 +++ test/__fixtures__/custom-webpack/manifest.yml | 7 ++ .../actions/mock.config.js | 3 + test/build.actions.test.js | 69 ++++++++++- 5 files changed, 155 insertions(+), 46 deletions(-) create mode 100644 test/__fixtures__/custom-webpack/actions/actionname/action.js create mode 100644 test/__fixtures__/custom-webpack/manifest.yml create mode 100644 test/__fixtures__/sample-app-includes/actions/mock.config.js diff --git a/src/build-actions.js b/src/build-actions.js index 4f1220f..ddc7258 100644 --- a/src/build-actions.js +++ b/src/build-actions.js @@ -13,9 +13,55 @@ governing permissions and limitations under the License. const fs = require('fs-extra') const path = require('path') const webpack = require('webpack') +const globby = require('globby') const utils = require('./utils') const aioLogger = require('@adobe/aio-lib-core-logging')('@adobe/aio-lib-runtime:action-builder', { provider: 'debug' }) +const getWebpackConfig = async (actionPath, root, tempBuildDir, outBuildFilename) => { + let parentDir = path.dirname(actionPath) + const rootParent = path.normalize(path.dirname(root)) + let configPath = null + + do { + const paths = await globby([path.join(parentDir, '*config.js')]) + if (paths && paths.length > 0) { + configPath = paths[0] + } + parentDir = path.dirname(parentDir) + } while (parentDir !== rootParent && !configPath) + // default empty + const config = configPath ? require(configPath) : {} + // entry [] must include action path + config.entry = config.entry || [] + config.entry.push(actionPath) + // if output exists, do not overwrite libraryTarget, default to commonjs2 + config.output = config.output || { libraryTarget: 'commonjs2' } + config.output.path = tempBuildDir + config.output.filename = outBuildFilename + // target MUST be node + config.target = 'node' + // default to production mode + config.mode = config.mode || 'production' + // default optimization to NOT minimize + config.optimization = config.optimization || { + // error on minification for some libraries + minimize: false + } + // the following lines are used to require es6 module, e.g.node-fetch which is used by azure sdk + config.resolve = config.resolve || {} + // extensions needs to include .js and .json + config.resolve.extensions = config.resolve.extensions || [] + config.resolve.extensions.push('.js', '.json') + // mainFields needs to include 'main' + config.resolve.mainFields = config.resolve.mainFields || [] + config.resolve.mainFields.push('main') + // we have 1 required plugin to make sure is present + config.plugins = config.plugins || [] + config.plugins.push(new webpack.DefinePlugin({ WEBPACK_ACTION_BUILD: 'true' })) + + aioLogger.debug(`merged webpack config : ${JSON.stringify(config, 0, 2)}`) + return config +} // need config.root // config.actions.dist const buildAction = async (zipFileName, action, root, dist) => { @@ -60,51 +106,26 @@ const buildAction = async (zipFileName, action, root, dist) => { } else { const outBuildFilename = 'index.js' // `${name}.tmp.js` // if not directory => package and minify to single file - const compiler = webpack({ - entry: [ - actionPath - ], - output: { - path: tempBuildDir, - filename: outBuildFilename, - libraryTarget: 'commonjs2' - }, - // see https://webpack.js.org/configuration/mode/ - mode: 'production', - target: 'node', - optimization: { - // error on minification for some libraries - minimize: false - }, - // the following lines are used to require es6 module, e.g.node-fetch which is used by azure sdk - resolve: { - extensions: ['.js', '.json'], - mainFields: ['main'] - }, - plugins: [new webpack.DefinePlugin( - { - WEBPACK_ACTION_BUILD: JSON.stringify(true) - })] - // todo remove packages from bundled file that are available in runtime (add the deps of deps as well) - // disabled for now as we need to consider versions (at least majors) to avoid nasty bugs - // ,externals: ['express', 'request', 'request-promise', 'body-parser', 'openwhisk'] - }) + const webpackConfig = await getWebpackConfig(actionPath, root, tempBuildDir, outBuildFilename) + const compiler = webpack(webpackConfig) // run the compiler and wait for a result - await new Promise((resolve, reject) => compiler.run((err, stats) => { - if (err) { - reject(err) - } - // stats must be defined at this point - const info = stats.toJson() - if (stats.hasWarnings()) { - aioLogger.debug(`webpack compilation warnings:\n${info.warnings}`) - } - if (stats.hasErrors()) { - reject(new Error(`action build failed, webpack compilation errors:\n${info.errors}`)) - } - return resolve(stats) - })) + await new Promise((resolve, reject) => { + compiler.run((err, stats) => { + if (err) { + reject(err) + } + // stats must be defined at this point + const info = stats.toJson() + if (stats.hasWarnings()) { + aioLogger.warn(`webpack compilation warnings:\n${info.warnings}`) + } + if (stats.hasErrors()) { + reject(new Error(`action build failed, webpack compilation errors:\n${info.errors}`)) + } + return resolve(stats) + }) + }) } // todo: split out zipping diff --git a/test/__fixtures__/custom-webpack/actions/actionname/action.js b/test/__fixtures__/custom-webpack/actions/actionname/action.js new file mode 100644 index 0000000..a18f1ec --- /dev/null +++ b/test/__fixtures__/custom-webpack/actions/actionname/action.js @@ -0,0 +1,15 @@ +/* +Copyright 2019 Adobe. All rights reserved. +This file is licensed to you 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 REPRESENTATIONS +OF ANY KIND, either express or implied. See the License for the specific language +governing permissions and limitations under the License. +*/ +function main (args) { + return 'hello' +} +exports.main = main diff --git a/test/__fixtures__/custom-webpack/manifest.yml b/test/__fixtures__/custom-webpack/manifest.yml new file mode 100644 index 0000000..9d544a6 --- /dev/null +++ b/test/__fixtures__/custom-webpack/manifest.yml @@ -0,0 +1,7 @@ +packages: + __APP_PACKAGE__: + actions: + action: + function: actions/actionname/action.js + web: yes + runtime: 'nodejs:12' diff --git a/test/__fixtures__/sample-app-includes/actions/mock.config.js b/test/__fixtures__/sample-app-includes/actions/mock.config.js new file mode 100644 index 0000000..078df05 --- /dev/null +++ b/test/__fixtures__/sample-app-includes/actions/mock.config.js @@ -0,0 +1,3 @@ +module.exports = { + "mode": "none" +} diff --git a/test/build.actions.test.js b/test/build.actions.test.js index 42ee45d..133f3c6 100644 --- a/test/build.actions.test.js +++ b/test/build.actions.test.js @@ -292,7 +292,7 @@ describe('build by bundling js action file with webpack', () => { 'manifest.yml': global.fixtureFile('/sample-app-includes/manifest.yml'), 'package.json': global.fixtureFile('/sample-app-includes/package.json') }) - globby.mockReturnValue(['/includeme.txt']) + globby.mockReturnValueOnce(['/includeme.txt']) await buildActions(global.sampleAppIncludesConfig) expect(webpackMock.run).toHaveBeenCalledTimes(1) expect(webpack).toHaveBeenCalledWith(expect.objectContaining({ @@ -307,6 +307,69 @@ describe('build by bundling js action file with webpack', () => { expect(Object.keys(global.fakeFileSystem.files())).toEqual(expect.arrayContaining(['/includeme.txt'])) }) + test('should bundle a single action file using webpack and zip it with includes using webpack.config.js', async () => { + // global.loadFs(vol, 'sample-app-includes') + global.fakeFileSystem.reset() + global.fakeFileSystem.addJson({ + 'actions/action.js': global.fixtureFile('/sample-app-includes/actions/action.js'), + 'includeme.txt': global.fixtureFile('/sample-app-includes/includeme.txt'), + 'actions/mock.config.js': global.fixtureFile('/sample-app-includes/actions/mock.config.js'), + 'manifest.yml': global.fixtureFile('/sample-app-includes/manifest.yml'), + 'package.json': global.fixtureFile('/sample-app-includes/package.json') + }) + globby.mockReturnValueOnce(['/includeme.txt']) + globby.mockReturnValueOnce(['actions/mock.config.js']) + + jest.mock('actions/mock.config.js', () => { + return { mode: 'none' } + }, { virtual: true }) + + await buildActions(global.sampleAppIncludesConfig) + expect(webpackMock.run).toHaveBeenCalledTimes(1) + expect(webpack).toHaveBeenCalledWith(expect.objectContaining({ + entry: [path.normalize('/actions/action.js')], + output: expect.objectContaining({ + path: path.normalize('/dist/actions/action-temp'), + filename: 'index.js' + }) + })) + expect(utils.zip).toHaveBeenCalledWith(path.normalize('/dist/actions/action-temp'), + path.normalize('/dist/actions/action.zip')) + expect(Object.keys(global.fakeFileSystem.files())).toEqual(expect.arrayContaining(['/includeme.txt'])) + }) + + test('should bundle a single action file using webpack and zip it with includes using webpack.config.js in actions root folder', async () => { + // global.loadFs(vol, 'sample-app-includes') + global.fakeFileSystem.reset() + global.fakeFileSystem.addJson({ + 'actions/actionname/action.js': global.fixtureFile('/custom-webpack/actions/actionname/action.js'), + 'manifest.yml': global.fixtureFile('/custom-webpack/manifest.yml') + }) + // first call to globby is for processing includes, second call is to get/find webpack config + globby.mockReturnValueOnce([]) + globby.mockReturnValueOnce([]) // call is to actions/actionname/*.config.js + globby.mockReturnValueOnce(['actions/mock2.config.js']) + + jest.mock('actions/mock2.config.js', () => { + return { mode: 'nope' } + }, { virtual: true }) + + const clonedConfig = deepClone(global.sampleAppIncludesConfig) + clonedConfig.manifest.full.packages.__APP_PACKAGE__.actions.action.function = 'actions/actionname/action.js' + await buildActions(clonedConfig) + expect(webpackMock.run).toHaveBeenCalledTimes(1) + expect(webpack).toHaveBeenCalledWith(expect.objectContaining({ + mode: 'nope', + entry: [path.normalize('/actions/actionname/action.js')], + output: expect.objectContaining({ + path: path.normalize('/dist/actions/action-temp'), + filename: 'index.js' + }) + })) + expect(utils.zip).toHaveBeenCalledWith(path.normalize('/dist/actions/action-temp'), + path.normalize('/dist/actions/action.zip')) + }) + test('should bundle a single action file using webpack and zip it with manifest named package', async () => { // global.loadFs(vol, 'named-package') global.fakeFileSystem.reset() @@ -361,7 +424,7 @@ describe('build by bundling js action file with webpack', () => { warnings: 'fake warnings' }) await buildActions(config) - expect(mockLogger.debug).toHaveBeenCalledWith('webpack compilation warnings:\nfake warnings') + expect(mockLogger.warn).toHaveBeenCalledWith('webpack compilation warnings:\nfake warnings') }) test('should throw if webpack returns an error ', async () => { @@ -380,7 +443,7 @@ describe('build by bundling js action file with webpack', () => { warnings: 'fake warnings' }) await expect(buildActions(config)).rejects.toThrow('action build failed, webpack compilation errors:\nfake errors') - expect(mockLogger.debug).toHaveBeenCalledWith('webpack compilation warnings:\nfake warnings') + expect(mockLogger.warn).toHaveBeenCalledWith('webpack compilation warnings:\nfake warnings') }) }) From 1ac02031668246bbe3ddb8c3249b0feef20fb1e4 Mon Sep 17 00:00:00 2001 From: Jesse MacFadyen Date: Wed, 3 Feb 2021 15:52:47 -0800 Subject: [PATCH 2/7] jest-haste-map: Haste module naming collision --- test/__fixtures__/named-package/actions/action-zip/package.json | 2 +- test/__fixtures__/named-package/package.json | 2 +- test/__fixtures__/sample-app/actions/action-zip/package.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/test/__fixtures__/named-package/actions/action-zip/package.json b/test/__fixtures__/named-package/actions/action-zip/package.json index 2124c05..e25a888 100644 --- a/test/__fixtures__/named-package/actions/action-zip/package.json +++ b/test/__fixtures__/named-package/actions/action-zip/package.json @@ -1,5 +1,5 @@ { - "name": "hellozip", + "name": "named-action-hellozip", "version": "1.0.0", "description": "", "main": "index.js", diff --git a/test/__fixtures__/named-package/package.json b/test/__fixtures__/named-package/package.json index 93abd6f..71b9122 100644 --- a/test/__fixtures__/named-package/package.json +++ b/test/__fixtures__/named-package/package.json @@ -1,4 +1,4 @@ { "version": "1.0.0", - "name": "sample-app" + "name": "named-package" } diff --git a/test/__fixtures__/sample-app/actions/action-zip/package.json b/test/__fixtures__/sample-app/actions/action-zip/package.json index 2124c05..f2b394d 100644 --- a/test/__fixtures__/sample-app/actions/action-zip/package.json +++ b/test/__fixtures__/sample-app/actions/action-zip/package.json @@ -1,5 +1,5 @@ { - "name": "hellozip", + "name": "sample-app-hellozip", "version": "1.0.0", "description": "", "main": "index.js", From 7aa8640ac03340d77ae126ec6a9cd5e491b3c6c4 Mon Sep 17 00:00:00 2001 From: Jesse MacFadyen Date: Wed, 3 Feb 2021 22:44:58 -0800 Subject: [PATCH 3/7] *config.js becomes more correctly *webpack-config.js --- src/build-actions.js | 2 +- test/build.actions.test.js | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/build-actions.js b/src/build-actions.js index ddc7258..62e988d 100644 --- a/src/build-actions.js +++ b/src/build-actions.js @@ -23,7 +23,7 @@ const getWebpackConfig = async (actionPath, root, tempBuildDir, outBuildFilename let configPath = null do { - const paths = await globby([path.join(parentDir, '*config.js')]) + const paths = await globby([path.join(parentDir, '*webpack-config.js')]) if (paths && paths.length > 0) { configPath = paths[0] } diff --git a/test/build.actions.test.js b/test/build.actions.test.js index 133f3c6..aca1eeb 100644 --- a/test/build.actions.test.js +++ b/test/build.actions.test.js @@ -307,7 +307,7 @@ describe('build by bundling js action file with webpack', () => { expect(Object.keys(global.fakeFileSystem.files())).toEqual(expect.arrayContaining(['/includeme.txt'])) }) - test('should bundle a single action file using webpack and zip it with includes using webpack.config.js', async () => { + test('should bundle a single action file using webpack and zip it with includes using webpack-config.js', async () => { // global.loadFs(vol, 'sample-app-includes') global.fakeFileSystem.reset() global.fakeFileSystem.addJson({ @@ -333,12 +333,13 @@ describe('build by bundling js action file with webpack', () => { filename: 'index.js' }) })) + expect(globby).toHaveBeenCalledWith(expect.arrayContaining(['/actions/*webpack-config.js'])) expect(utils.zip).toHaveBeenCalledWith(path.normalize('/dist/actions/action-temp'), path.normalize('/dist/actions/action.zip')) expect(Object.keys(global.fakeFileSystem.files())).toEqual(expect.arrayContaining(['/includeme.txt'])) }) - test('should bundle a single action file using webpack and zip it with includes using webpack.config.js in actions root folder', async () => { + test('should bundle a single action file using webpack and zip it with includes using webpack-config.js in actions root folder', async () => { // global.loadFs(vol, 'sample-app-includes') global.fakeFileSystem.reset() global.fakeFileSystem.addJson({ From 9a2c0f418c964e36897d7cca367b0e4601d4d8f1 Mon Sep 17 00:00:00 2001 From: Jesse MacFadyen Date: Wed, 3 Feb 2021 22:50:02 -0800 Subject: [PATCH 4/7] oops, windows ... normalize that path --- test/build.actions.test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/build.actions.test.js b/test/build.actions.test.js index aca1eeb..2a997dd 100644 --- a/test/build.actions.test.js +++ b/test/build.actions.test.js @@ -333,7 +333,7 @@ describe('build by bundling js action file with webpack', () => { filename: 'index.js' }) })) - expect(globby).toHaveBeenCalledWith(expect.arrayContaining(['/actions/*webpack-config.js'])) + expect(globby).toHaveBeenCalledWith(expect.arrayContaining([path.normalize('/actions/*webpack-config.js')])) expect(utils.zip).toHaveBeenCalledWith(path.normalize('/dist/actions/action-temp'), path.normalize('/dist/actions/action.zip')) expect(Object.keys(global.fakeFileSystem.files())).toEqual(expect.arrayContaining(['/includeme.txt'])) From 7ebfbed38c129015d261023ca062e35c56651cdc Mon Sep 17 00:00:00 2001 From: Moritz Raho Date: Thu, 4 Feb 2021 13:11:23 +0100 Subject: [PATCH 5/7] fix messed config multiple actions + fix duplicates + preserve important fields --- src/build-actions.js | 29 +++++++++++--- test/build.actions.test.js | 81 +++++++++++++++++++++++++++----------- 2 files changed, 82 insertions(+), 28 deletions(-) diff --git a/src/build-actions.js b/src/build-actions.js index 62e988d..9d95c61 100644 --- a/src/build-actions.js +++ b/src/build-actions.js @@ -16,6 +16,11 @@ const webpack = require('webpack') const globby = require('globby') const utils = require('./utils') const aioLogger = require('@adobe/aio-lib-core-logging')('@adobe/aio-lib-runtime:action-builder', { provider: 'debug' }) +const cloneDeep = require('lodash.clonedeep') + +const uniqueArr = (items) => { + return [...new Set(items)] +} const getWebpackConfig = async (actionPath, root, tempBuildDir, outBuildFilename) => { let parentDir = path.dirname(actionPath) @@ -30,12 +35,20 @@ const getWebpackConfig = async (actionPath, root, tempBuildDir, outBuildFilename parentDir = path.dirname(parentDir) } while (parentDir !== rootParent && !configPath) // default empty - const config = configPath ? require(configPath) : {} + const userConfig = configPath ? require(configPath) : {} + // needs cloning because require has a cache, so we make sure to not touch the userConfig + const config = cloneDeep(userConfig) + // entry [] must include action path config.entry = config.entry || [] config.entry.push(actionPath) - // if output exists, do not overwrite libraryTarget, default to commonjs2 - config.output = config.output || { libraryTarget: 'commonjs2' } + config.entry = uniqueArr(config.entry) + + // if output exists, default to commonjs2 + config.output = config.output || {} + if (config.output.libraryTarget === undefined) { + config.output.libraryTarget = 'commonjs2' + } config.output.path = tempBuildDir config.output.filename = outBuildFilename // target MUST be node @@ -43,21 +56,27 @@ const getWebpackConfig = async (actionPath, root, tempBuildDir, outBuildFilename // default to production mode config.mode = config.mode || 'production' // default optimization to NOT minimize - config.optimization = config.optimization || { + config.optimization = config.optimization || {} + if (config.optimization.minimize === undefined) { // error on minification for some libraries - minimize: false + config.optimization.minimize = false } // the following lines are used to require es6 module, e.g.node-fetch which is used by azure sdk config.resolve = config.resolve || {} // extensions needs to include .js and .json config.resolve.extensions = config.resolve.extensions || [] config.resolve.extensions.push('.js', '.json') + config.resolve.extensions = uniqueArr(config.resolve.extensions) + // mainFields needs to include 'main' config.resolve.mainFields = config.resolve.mainFields || [] config.resolve.mainFields.push('main') + config.resolve.mainFields = uniqueArr(config.resolve.mainFields) + // we have 1 required plugin to make sure is present config.plugins = config.plugins || [] config.plugins.push(new webpack.DefinePlugin({ WEBPACK_ACTION_BUILD: 'true' })) + // NOTE: no need to make the array unique here, all plugins are different and created via new aioLogger.debug(`merged webpack config : ${JSON.stringify(config, 0, 2)}`) return config diff --git a/test/build.actions.test.js b/test/build.actions.test.js index 2a997dd..becc5ec 100644 --- a/test/build.actions.test.js +++ b/test/build.actions.test.js @@ -318,21 +318,39 @@ describe('build by bundling js action file with webpack', () => { 'package.json': global.fixtureFile('/sample-app-includes/package.json') }) globby.mockReturnValueOnce(['/includeme.txt']) - globby.mockReturnValueOnce(['actions/mock.config.js']) - - jest.mock('actions/mock.config.js', () => { - return { mode: 'none' } + globby.mockReturnValueOnce(['actions/mock.webpack-config.js']) + + jest.mock('actions/mock.webpack-config.js', () => { + return { + mode: 'none', + optimization: { somefakefield: true }, + output: { fake: false }, + entry: ['file.js'], + resolve: { + extensions: ['html', 'json', 'css'], + mainFields: ['another'], + anotherFake: ['yo'] + }, + plugins: ['hello'], + target: 'cannotovewrite' + } }, { virtual: true }) await buildActions(global.sampleAppIncludesConfig) expect(webpackMock.run).toHaveBeenCalledTimes(1) - expect(webpack).toHaveBeenCalledWith(expect.objectContaining({ - entry: [path.normalize('/actions/action.js')], - output: expect.objectContaining({ - path: path.normalize('/dist/actions/action-temp'), - filename: 'index.js' - }) - })) + expect(webpack).toHaveBeenCalledWith({ + entry: ['file.js', path.normalize('/actions/action.js')], + mode: 'none', + optimization: { minimize: false, somefakefield: true }, + output: { fake: false, filename: 'index.js', libraryTarget: 'commonjs2', path: path.normalize('/dist/actions/action-temp') }, + plugins: ['hello', {}], + resolve: { + anotherFake: ['yo'], + extensions: ['html', 'json', 'css', '.js', '.json'], + mainFields: ['another', 'main'] + }, + target: 'node' + }) expect(globby).toHaveBeenCalledWith(expect.arrayContaining([path.normalize('/actions/*webpack-config.js')])) expect(utils.zip).toHaveBeenCalledWith(path.normalize('/dist/actions/action-temp'), path.normalize('/dist/actions/action.zip')) @@ -349,24 +367,41 @@ describe('build by bundling js action file with webpack', () => { // first call to globby is for processing includes, second call is to get/find webpack config globby.mockReturnValueOnce([]) globby.mockReturnValueOnce([]) // call is to actions/actionname/*.config.js - globby.mockReturnValueOnce(['actions/mock2.config.js']) - - jest.mock('actions/mock2.config.js', () => { - return { mode: 'nope' } + globby.mockReturnValueOnce(['actions/mock2.webpack-config.js']) + + jest.mock('actions/mock2.webpack-config.js', () => { + return { + mode: 'none', + optimization: { somefakefield: true, minimize: true }, + output: { fake: false, libraryTarget: 'fake' }, + entry: ['file.js'], + resolve: { + extensions: ['html', 'json', 'css'], + mainFields: ['another'], + anotherFake: ['yo'] + }, + plugins: ['hello'], + target: 'cannotovewrite' + } }, { virtual: true }) const clonedConfig = deepClone(global.sampleAppIncludesConfig) clonedConfig.manifest.full.packages.__APP_PACKAGE__.actions.action.function = 'actions/actionname/action.js' await buildActions(clonedConfig) expect(webpackMock.run).toHaveBeenCalledTimes(1) - expect(webpack).toHaveBeenCalledWith(expect.objectContaining({ - mode: 'nope', - entry: [path.normalize('/actions/actionname/action.js')], - output: expect.objectContaining({ - path: path.normalize('/dist/actions/action-temp'), - filename: 'index.js' - }) - })) + expect(webpack).toHaveBeenCalledWith({ + entry: ['file.js', path.normalize('/actions/actionname/action.js')], + mode: 'none', + optimization: { minimize: true, somefakefield: true }, + output: { fake: false, filename: 'index.js', libraryTarget: 'fake', path: path.normalize('/dist/actions/action-temp') }, + plugins: ['hello', {}], + resolve: { + anotherFake: ['yo'], + extensions: ['html', 'json', 'css', '.js', '.json'], + mainFields: ['another', 'main'] + }, + target: 'node' + }) expect(utils.zip).toHaveBeenCalledWith(path.normalize('/dist/actions/action-temp'), path.normalize('/dist/actions/action.zip')) }) From 584fa61e8a631a0ef7584192264868677f68f982 Mon Sep 17 00:00:00 2001 From: Moritz Raho Date: Thu, 4 Feb 2021 13:35:36 +0100 Subject: [PATCH 6/7] fix relative entry files --- src/build-actions.js | 7 +++++++ test/build.actions.test.js | 14 +++++++------- 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/src/build-actions.js b/src/build-actions.js index 9d95c61..2f646dc 100644 --- a/src/build-actions.js +++ b/src/build-actions.js @@ -43,6 +43,13 @@ const getWebpackConfig = async (actionPath, root, tempBuildDir, outBuildFilename config.entry = config.entry || [] config.entry.push(actionPath) config.entry = uniqueArr(config.entry) + // make sure filepaths are resolved from the config dir + config.entry = config.entry.map(f => { + if (!path.isAbsolute(f)) { + return path.resolve(path.dirname(configPath), f) + } + return f + }) // if output exists, default to commonjs2 config.output = config.output || {} diff --git a/test/build.actions.test.js b/test/build.actions.test.js index becc5ec..300cad6 100644 --- a/test/build.actions.test.js +++ b/test/build.actions.test.js @@ -307,13 +307,13 @@ describe('build by bundling js action file with webpack', () => { expect(Object.keys(global.fakeFileSystem.files())).toEqual(expect.arrayContaining(['/includeme.txt'])) }) - test('should bundle a single action file using webpack and zip it with includes using webpack-config.js', async () => { + test('should bundle a single action file using webpack and zip it with includes using webpack-config.js in actions root', async () => { // global.loadFs(vol, 'sample-app-includes') global.fakeFileSystem.reset() global.fakeFileSystem.addJson({ 'actions/action.js': global.fixtureFile('/sample-app-includes/actions/action.js'), 'includeme.txt': global.fixtureFile('/sample-app-includes/includeme.txt'), - 'actions/mock.config.js': global.fixtureFile('/sample-app-includes/actions/mock.config.js'), + 'actions/mock.webpackconfig.js': global.fixtureFile('/sample-app-includes/actions/mock.config.js'), 'manifest.yml': global.fixtureFile('/sample-app-includes/manifest.yml'), 'package.json': global.fixtureFile('/sample-app-includes/package.json') }) @@ -339,7 +339,7 @@ describe('build by bundling js action file with webpack', () => { await buildActions(global.sampleAppIncludesConfig) expect(webpackMock.run).toHaveBeenCalledTimes(1) expect(webpack).toHaveBeenCalledWith({ - entry: ['file.js', path.normalize('/actions/action.js')], + entry: [path.resolve('actions/file.js'), path.normalize('/actions/action.js')], mode: 'none', optimization: { minimize: false, somefakefield: true }, output: { fake: false, filename: 'index.js', libraryTarget: 'commonjs2', path: path.normalize('/dist/actions/action-temp') }, @@ -357,7 +357,7 @@ describe('build by bundling js action file with webpack', () => { expect(Object.keys(global.fakeFileSystem.files())).toEqual(expect.arrayContaining(['/includeme.txt'])) }) - test('should bundle a single action file using webpack and zip it with includes using webpack-config.js in actions root folder', async () => { + test('should bundle a single action file using webpack and zip it with includes using webpack-config.js in actions folder', async () => { // global.loadFs(vol, 'sample-app-includes') global.fakeFileSystem.reset() global.fakeFileSystem.addJson({ @@ -367,9 +367,9 @@ describe('build by bundling js action file with webpack', () => { // first call to globby is for processing includes, second call is to get/find webpack config globby.mockReturnValueOnce([]) globby.mockReturnValueOnce([]) // call is to actions/actionname/*.config.js - globby.mockReturnValueOnce(['actions/mock2.webpack-config.js']) + globby.mockReturnValueOnce(['actions/actionname/mock2.webpack-config.js']) - jest.mock('actions/mock2.webpack-config.js', () => { + jest.mock('actions/actionname/mock2.webpack-config.js', () => { return { mode: 'none', optimization: { somefakefield: true, minimize: true }, @@ -390,7 +390,7 @@ describe('build by bundling js action file with webpack', () => { await buildActions(clonedConfig) expect(webpackMock.run).toHaveBeenCalledTimes(1) expect(webpack).toHaveBeenCalledWith({ - entry: ['file.js', path.normalize('/actions/actionname/action.js')], + entry: [path.resolve('actions/actionname/file.js'), path.normalize('/actions/actionname/action.js')], mode: 'none', optimization: { minimize: true, somefakefield: true }, output: { fake: false, filename: 'index.js', libraryTarget: 'fake', path: path.normalize('/dist/actions/action-temp') }, From 242ddd45f65242a0caf43243093facab88c2a440 Mon Sep 17 00:00:00 2001 From: Moritz Raho Date: Thu, 4 Feb 2021 15:09:18 +0100 Subject: [PATCH 7/7] test cleanup --- test/__fixtures__/sample-app-includes/actions/mock.config.js | 3 --- test/build.actions.test.js | 1 - 2 files changed, 4 deletions(-) delete mode 100644 test/__fixtures__/sample-app-includes/actions/mock.config.js diff --git a/test/__fixtures__/sample-app-includes/actions/mock.config.js b/test/__fixtures__/sample-app-includes/actions/mock.config.js deleted file mode 100644 index 078df05..0000000 --- a/test/__fixtures__/sample-app-includes/actions/mock.config.js +++ /dev/null @@ -1,3 +0,0 @@ -module.exports = { - "mode": "none" -} diff --git a/test/build.actions.test.js b/test/build.actions.test.js index 300cad6..5e22667 100644 --- a/test/build.actions.test.js +++ b/test/build.actions.test.js @@ -313,7 +313,6 @@ describe('build by bundling js action file with webpack', () => { global.fakeFileSystem.addJson({ 'actions/action.js': global.fixtureFile('/sample-app-includes/actions/action.js'), 'includeme.txt': global.fixtureFile('/sample-app-includes/includeme.txt'), - 'actions/mock.webpackconfig.js': global.fixtureFile('/sample-app-includes/actions/mock.config.js'), 'manifest.yml': global.fixtureFile('/sample-app-includes/manifest.yml'), 'package.json': global.fixtureFile('/sample-app-includes/package.json') })