Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Behaviour of ncc'd libraries requiring code dynamically #479

Open
OlliV opened this issue Oct 7, 2019 · 7 comments
Open

Behaviour of ncc'd libraries requiring code dynamically #479

OlliV opened this issue Oct 7, 2019 · 7 comments

Comments

@OlliV
Copy link

OlliV commented Oct 7, 2019

It seems that by default ncc (or webpack) isn't configured to preserve exports. Is it possible to do that?

@TooTallNate
Copy link
Member

Can you elaborate on what you mean? All of our main builders are indeed compiled via ncc, and the exports remain intact.

Also, this simple example preserves the exports:

// t.js
exports.foo = 'bar';
$ ncc build t.js
1kB  dist/index.js
1kB  [285ms] - ncc 0.16.0
> require('./dist')
{ foo: 'bar' }

@OlliV
Copy link
Author

OlliV commented Oct 8, 2019

Interesting. I was using TS and all I got was this:

console.log(require('...'));
{ }

I need to try to find the min reproduction of the issue. I was using several exports and a default export. Once that didn't work I also tried to reproduce TS-like exports in the node.js way but I was still getting an empty object.

@OlliV
Copy link
Author

OlliV commented Oct 8, 2019

Ok the issue seems to be related to npm link and dynamic requires.

Let's say you have project-1 that is built with ncc and there is a function in project-1 that can dynamically require and execute code from any path given as an arg.

Then project-2 uses npm link project-1 and calls that function passing a path of file in its own source tree. So far everything works and the code is loaded and can be executed by project-1. However, if the file from project-2 that is being executed by project-1 now also tries to require something from project-1 only in this case will require('project-1') return an empty object.

@OlliV OlliV changed the title Is it possible to use ncc for libraries? Behaviour of ncc'd libraries requiring code dynamically Oct 8, 2019
@OlliV
Copy link
Author

OlliV commented Oct 8, 2019

I have a very interesting repro without npm link. It seems like dynamic require works fine if the code build with ncc is not in the node_modules directory.

https://files-8mwa86l42.now.sh

ncc-issue-repro/
ncc-issue-repro/package.json
ncc-issue-repro/yarn.lock
ncc-issue-repro/index.js
ncc-issue-repro/node_modules/
ncc-issue-repro/node_modules/.bin/
ncc-issue-repro/node_modules/.bin/micri
ncc-issue-repro/node_modules/.yarn-integrity
ncc-issue-repro/node_modules/test/
ncc-issue-repro/node_modules/test/package.json
ncc-issue-repro/node_modules/test/yarn.lock
ncc-issue-repro/node_modules/test/tsconfig.json
ncc-issue-repro/node_modules/test/src/
ncc-issue-repro/node_modules/test/src/index.ts
ncc-issue-repro/node_modules/test/dist/
ncc-issue-repro/node_modules/test/dist/index.d.ts
ncc-issue-repro/node_modules/test/dist/index.js
ncc-issue-repro/test/
ncc-issue-repro/test/package.json
ncc-issue-repro/test/yarn.lock
ncc-issue-repro/test/tsconfig.json
ncc-issue-repro/test/src/
ncc-issue-repro/test/src/index.ts
ncc-issue-repro/test/dist/
ncc-issue-repro/test/dist/index.js
ncc-issue-repro/test/dist/index.d.ts
ncc-issue-repro/run.sh

I'm running here first the index.js file that just requires test from both the direct subdir as well as using the standard module require string format, and that works fine. 'here' is a string exported by the module compiled with ncc.

Now things get really interesting if I execute the module compiled with ncc and require index.js dynamically from there. As you can see from the logs the second case, which should be the normal use case, now sees undefined.

 ./run.sh
+ node index.js
Path: /home/hbp/tmp/ncc-issue-repro/index.js
node_modules: here
Path: /home/hbp/tmp/ncc-issue-repro/index.js
local here
+ node ./node_modules/test/dist/index.js
Path: /home/hbp/tmp/ncc-issue-repro/index.js
node_modules: undefined
Path: /home/hbp/tmp/ncc-issue-repro/index.js
local here

@OlliV
Copy link
Author

OlliV commented Oct 8, 2019

Here is the code so you don't necessarily need to open the tar file:

index.js

const {findMe: a} = require('test');
console.log('node_modules:', a);

const {findMe: b} = require('./test');
console.log('local', b);

test/index.js

const {findMe: a} = require('test');
console.log('node_modules:', a);

const {findMe: b} = require('./test');
console.log('local', b);
[hbp@hbp-mac-fedora]~/tmp/ncc-issue-repro% cat test/dist/index.js
module.exports=function(e,r){"use strict";var t={};function __webpack_require__(r){if(t[r]){return t[r].exports}var u=t[r]={i:r,l:false,exports:{}};e[r].call(u.exports,u,u.exports,__webpack_require__);u.l=true;return u.exports}__webpack_require__.ab=__dirname+"/";function startup(){return __webpack_require__(325)}return startup()}({325:function(e,r,t){"use strict";var u=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(r,"__esModule",{value:true});const n=u(t(622));r.findMe="here";function fn(){const e=n.default.resolve(process.cwd(),"index.js");console.log(`Path: ${e}`);require(e)}fn()},622:function(e){e.exports=require("path")}});

test/index.ts

import path from 'path';

export const findMe = 'here';

function fn() {
    const filePath = path.resolve(process.cwd(), 'index.js');
    console.log(`Path: ${filePath}`);
    require(filePath);
}

fn();

@OlliV
Copy link
Author

OlliV commented Oct 8, 2019

Further on it seems this occurs if I require the same file that executed my code. If I use a physically copy of index.js that contains findMe then it's fine. Symlink doesn't work. The copy of the file can be exact copy but it must be located in a different path and can't be linked.

OlliV added a commit to turist-cloud/micri that referenced this issue Oct 9, 2019
The command line interface adds a lot of bulk to Micri and causes
weird issue with ncc vercel/ncc#479

Also the command line interface is likely slower to execute than a
single direct non-dynamic require.
OlliV added a commit to turist-cloud/micri that referenced this issue Oct 10, 2019
The command line interface adds a lot of bulk to Micri and causes
weird issue with ncc vercel/ncc#479

Also the command line interface is likely slower to execute than a
single direct non-dynamic require.
@bradennapier
Copy link

Yeah I think I may be running into this when trying to use the eslint cli packaged in for a github action?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants