From a308072cd99cd97d7fff02c73fbf9d54ee4d61d3 Mon Sep 17 00:00:00 2001 From: Michael van Engelshoven Date: Fri, 15 Sep 2023 08:57:41 +0200 Subject: [PATCH] added experimental support for symlinked modules When linking external dependencies using `npm_link`, rollups commonjs plugin does not process files in the symlinked directory correctly. To support this, rollup need the `preserveSymlinks` setting to be true. Since we cannot assess at the moment whether this setting will break some other build, we put it behind an experimental flag. So you need to set the environment varialbe `FAUCET_EXPERIMENTAL_SYMLINKS` to `"true"` to enable preserving symlinks. --- lib/bundle/config.js | 9 +++- .../fixtures/external/cjs-module/index.js | 3 ++ test/unit/fixtures/src/import-symlinked.js | 3 ++ test/unit/test_bundling.js | 46 +++++++++++++++++++ 4 files changed, 59 insertions(+), 2 deletions(-) create mode 100644 test/unit/fixtures/external/cjs-module/index.js create mode 100644 test/unit/fixtures/src/import-symlinked.js diff --git a/lib/bundle/config.js b/lib/bundle/config.js index 7e020fa..449c633 100644 --- a/lib/bundle/config.js +++ b/lib/bundle/config.js @@ -88,8 +88,13 @@ function generateConfig({ externals, format, exports, // eslint-disable-next-lin plugins = plugins.concat([ nodeResolve({ extensions }), - commonjs({ include: "node_modules/**" }) + commonjs({ include: /node_modules/ }) ]); + + if(process.env.FAUCET_EXPERIMENTAL_SYMLINKS === "true") { + cfg.preserveSymlinks = true; + } + if(compact) { cfg.compact = true; plugins = plugins.concat(determineCompacting(compact)); @@ -111,7 +116,7 @@ function generateConfig({ externals, format, exports, // eslint-disable-next-lin } // distinguish between (roughly) read and write settings - let read = ["external", "plugins"]; + let read = ["external", "plugins", "preserveSymlinks"]; return Object.keys(cfg).reduce((memo, key) => { let type = read.includes(key) ? "readConfig" : "writeConfig"; memo[type][key] = cfg[key]; diff --git a/test/unit/fixtures/external/cjs-module/index.js b/test/unit/fixtures/external/cjs-module/index.js new file mode 100644 index 0000000..785a4fc --- /dev/null +++ b/test/unit/fixtures/external/cjs-module/index.js @@ -0,0 +1,3 @@ +exports.dummy = { + some: "dummy value" +}; diff --git a/test/unit/fixtures/src/import-symlinked.js b/test/unit/fixtures/src/import-symlinked.js new file mode 100644 index 0000000..08813b1 --- /dev/null +++ b/test/unit/fixtures/src/import-symlinked.js @@ -0,0 +1,3 @@ +import { dummy } from "some-cjs-module"; + +console.log(dummy); // eslint-disable-line no-console diff --git a/test/unit/test_bundling.js b/test/unit/test_bundling.js index c3f7d39..7da6d48 100644 --- a/test/unit/test_bundling.js +++ b/test/unit/test_bundling.js @@ -3,6 +3,7 @@ let { MockAssetManager, makeBundle, FIXTURES_DIR } = require("./util"); let faucetJS = require("../../lib").plugin; +const fs = require("fs"); let path = require("path"); let assert = require("assert"); @@ -412,4 +413,49 @@ console.log(\`[DUMMY] $\{util}\`); // eslint-disable-line no-console assetManager.assertWriteCount(1); }); }); + + describe("working with linked modules", () => { + // in case some set this env variable before + let initialFlagValue = process.env.FAUCET_EXPERIMENTAL_SYMLINKS; + + beforeEach(() => { + fs.symlinkSync( + path.resolve(FIXTURES_DIR, "./external/cjs-module"), + path.resolve(FIXTURES_DIR, "./node_modules/some-cjs-module"), + "dir" + ); + + process.env.FAUCET_EXPERIMENTAL_SYMLINKS = "true"; + }); + + afterEach(() => { + fs.unlinkSync(path.resolve(FIXTURES_DIR, "./node_modules/some-cjs-module")); + process.env.FAUCET_EXPERIMENTAL_SYMLINKS = initialFlagValue; + }); + + it("should preserve symlinks when env varialbe is set", () => { + let config = [{ + source: "./src/import-symlinked.js", + target: "./dist/bundle.js", + format: "CommonJS" + }]; + let assetManager = new MockAssetManager(FIXTURES_DIR); + + return faucetJS(config, assetManager, DEFAULT_OPTIONS)(). + then(() => { + assetManager.assertWrites([{ + filepath: path.resolve(FIXTURES_DIR, "./dist/bundle.js"), + content: makeBundle(` +'use strict'; + +var dummy = { + some: "dummy value" +}; + +console.log(dummy); // eslint-disable-line no-console +`) + }]); + }); + }); + }); });