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

Webpack building broken #1754

Closed
dl748 opened this issue Sep 15, 2020 · 18 comments · Fixed by #1757
Closed

Webpack building broken #1754

dl748 opened this issue Sep 15, 2020 · 18 comments · Fixed by #1757
Labels

Comments

@dl748
Copy link

dl748 commented Sep 15, 2020

Upgraded from 15.4.1 to 16.0.3 and now all my scripts built with webpack now fail with the error.

Everything seems to compile, but when i run the resulted js file, I get

TypeError: y18n is not a function

y18n: y18n({

If i modify the exported code to use y18n.y18n( then it works... also I needed to change all shim$1.Parser to shim$1.Parser.default

simple webpack.config.js // works in 15.4.1

var path = require('path');

module.exports = async (env, argv) => {
  let config = {
    mode: "development",
    entry: {
      "test": "./index.js",
    },
    output: {
      path: path.resolve(__dirname, "dist")
    },
    target: 'node',
    devtool: "source-map-inline",
  };
  return config;
}

index.js

var yargs = require('yargs');

console.log(yargs.argv);

webpack@4.44.1 with yargs@15.4.1 works

$ node dist/test.js
{ _: [], '$0': 'dist/test.js' }

webpack@4.44.1 with yargs@16.0.3 compiles but fails to run

$ node dist/test.js
dist/test.js:5012
    y18n: y18n({
          ^

TypeError: y18n is not a function
    at Object.<anonymous> (dist/test.js:5012:11)
    at Object../node_modules/yargs/build/index.cjs (dist/test.js:5045:30)
    at __webpack_require__ (dist/test.js:20:30)
    at Object../node_modules/yargs/index.cjs (dist/test.js:5061:32)
    at __webpack_require__ (dist/test.js:20:30)
    at Object../index.js (dist/test.js:96:13)
    at __webpack_require__ (dist/test.js:20:30)
    at dist/test.js:84:18
    at Object.<anonymous> (dist/test.js:87:10)
    at Module._compile (internal/modules/cjs/loader.js:1137:30)

Note: I was able to get it to work via some strange settings

var path = require('path');

module.exports = async (env, argv) => {
  let config = {
    mode: "development",
    entry: {
      "test": "./index.js",
    },
    output: {
      path: path.resolve(__dirname, "dist")
    },
    target: 'node',
    devtool: "source-map-inline",
    externals: {
      'y18n': 'commonjs2 y18n',
      'yargs-parser': 'commonjs2 yargs-parser',
    },
  };
  return config;
}

I had to explicitly tell webpack to import y18n and yargs-parser via commonjs2 methods.

@bcoe bcoe added the wontfix label Sep 16, 2020
@bcoe
Copy link
Member

bcoe commented Sep 16, 2020

@dl748 yargs now fully supports ESM, so in some cases there should be no need to WebPack. There's now an example of how to get things running in the browser in the examples/ folder.

I think perhaps you just need to webpack the browser.js entry point rather than the index, if the goal is to create a bundle.

@bcoe bcoe added docs and removed wontfix labels Sep 16, 2020
@bcoe
Copy link
Member

bcoe commented Sep 16, 2020

@dl748 may I ask why you're using yargs in the browser? as I took on the work to make this possible, one question I had was whether it would actually benefit many people.

@dl748
Copy link
Author

dl748 commented Sep 17, 2020

I'm not using a browser as you can see with my configuration. "target: 'node'". I generally use webpack to compile a typescript app to a single standalone app (.js file) so that i can run it on a machine that has node but can't install anything from a repository.

webpack will pull in the node_modules (except for binary specific, which i don't use)

I just created a simple (non typescript) example that also failed.

@Michael-Tajmajer-Bentley

I also use webpack on my nodeJs services. It keeps the clutter down and allows for quickly updating containers while troubleshooting issues inside of clusters.

@bcoe
Copy link
Member

bcoe commented Sep 17, 2020

@dl748 @ Michael-Tajmajer-Bentley I suggest opening an issue on Webpack too, and I'll happily take a patch to our docs.

My reasoning being that ESM should certainly be easily Webpacked, and I'm surprised that Webpack isn't properly consuming ESM modules.

@boneskull
Copy link
Contributor

fwiw ncc may be more suitable for this use-case. or even rollup. I can't imagine the node target is really first-class in webpack, and I am not surprised that it doesn't work well with Node.js' spec-compliant implementation

@bcoe
Copy link
Member

bcoe commented Sep 18, 2020

@boneskull ncc is a great suggestion 👍 hadn't thought of that. Unfortunately, for ESM, it looks like it won't support import.meta.url until it's updated to Webpack@5 -- but it works great for CommonJS.

@bcoe
Copy link
Member

bcoe commented Sep 18, 2020

@dl748 please take a look at the docs I've added:

#1757

Thanks for your help sorting this out.

@dl748
Copy link
Author

dl748 commented Sep 18, 2020

Ok, looks like yargs is a little broken..

  1. Webpack is loading packages by "module" (in the package.json) due to "target: 'node'"
    a. Webpack loads y18n's "module" -> y18n/build/lib/index.js (success)
    b. Webpack loads yargs-parser's "module" -> yargs-parser/build/lib/index.js (success)
    c. Webpack loads yargs "module" -> yargs/build/index.mjs (fails no such file)
    d. Webpack loads yargs "main" -> yargs/index.cjs (success)
  2. "Fixing" package.json to use ./index.mjs instead of ./build/index.mjs gives another error (import.meta.url) unsupported in ./lib/platform-shims/esm.mjs
    a. Issue found here -> How should we handle import.meta webpack/webpack#6719 support available in Webpack 5 I think, not 4, but there is a plugin that can be used to fix it -> https://www.npmjs.com/package/@open-wc/webpack-import-meta-loader

So when webpack is import yargs, it imports the "modules" of both y18n and yargs-parser, but then loads the cjs of yargs which is expecting the modules to be imported a completely different way.

@bcoe
Copy link
Member

bcoe commented Sep 18, 2020

@dl748 Ok, looks like yargs is a little broken.

In my opinion yargs isn't broken, Webpack is not properly resolving ESM and CJS dependencies (as #6719 indicates).

I think we should just document how to workaround this.

@dl748
Copy link
Author

dl748 commented Sep 18, 2020

according the package.json of yargs, there is no module to load as

  "module": "./build/index.mjs",

this file doesn't exist

so loading falls back to

  "main": "./index.cjs"

@bcoe
Copy link
Member

bcoe commented Sep 18, 2020

but there is a plugin that can be used to fix it -> https://www.npmjs.com/package/@open-wc/webpack-import-meta-loader

I think I'd rather just document how to create a CJS bundle for the time being. And, when Webpack 5 solves this problem I'm happy to document an alternative approach.

@bcoe
Copy link
Member

bcoe commented Sep 18, 2020

according the package.json of yargs, there is no module to load

@dl748 oh, that certainly does sound like a bug. Can we simplify our configuration if that's fixed?

I guess if that's fixed, things will start working once that import.meta issue is resolved. So, let's fix that bug, but not bother documenting how to build for ESM yet -- since it won't work.

@dl748
Copy link
Author

dl748 commented Sep 18, 2020

I think you meant to have it

  "module": "./index.mjs"

thats what i used to fix the initial issue.

@dl748
Copy link
Author

dl748 commented Sep 18, 2020

when running webpack

ERROR in /u/projects/repos/yargs/lib/platform-shims/esm.mjs 18:41
Module parse failed: Unexpected token (18:41)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
| const REQUIRE_DIRECTORY_ERROR = 'loading a directory of commands is not supported yet for ESM'
|
> const mainFilename = fileURLToPath(import.meta.url).split('node_modules')[0]
| const __dirname = fileURLToPath(import.meta.url)
|
 @ /u/projects/repos/yargs/index.mjs 4:0-58 7:28-43
 @ ./index.js

which at least LOOKS correct as its now loading the index.mjs now

@dl748
Copy link
Author

dl748 commented Sep 18, 2020

found a quick fix, could break some builds...

webpack.config.js

  resolve: {
    mainFields: [ 'main' ]
  }

This will force all modules to use the main or in yargs case, the commonjs build, instead of the module ones.

@bcoe
Copy link
Member

bcoe commented Sep 22, 2020

#1759 <-- the main issue should be fixed.

@bcoe
Copy link
Member

bcoe commented Sep 24, 2020

@dl748 I landed documentation for ncc and Webpack, please feel free to submit any recommendations based on your own experiences.

joshkel added a commit to rk-squared/rk-squared that referenced this issue May 17, 2021
This is a temporary measure to fix yargs/yargs#1754.  Webpack 5 would supposedly fix it properly.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants