nanoexpress / middlewares

Middleware packages for nanoexpress
20 stars 10 forks source link

@nanoexpress/middleware-schemator esModule import on cjs #24

Closed game5413 closed 3 years ago

game5413 commented 3 years ago

Bug Report

Is you/your team sponsoring this project

If your team sponsoring this project, please attach here your team lead or who purchased license GitHub login

Minimal reproducible repo

https://github.com/nanoexpress/middlewares/tree/master/packages/schemator

Current Behavior

const schemator = require('@nanoexpress/middleware-schemator/cjs');

got an error message:

Error [ERR_REQUIRE_ESM]: Must use import to load ES Module: D:\febryan\www\mindtrex-executive-microservice\node_modules\@nanoexpress\middleware-static-serve\static.es.js
require() of ES modules is not supported.
require() of D:\febryan\www\mindtrex-executive-microservice\node_modules\@nanoexpress\middleware-static-serve\static.es.js from D:\febryan\www\mindtrex-executive-microservice\node_modules\@nan
oexpress\middleware-schemator\cjs\schemator.cjs.js is an ES module file as it is a .js file whose nearest parent package.json contains "type": "module" which defines all .js files in that package scope as ES mo
dules.
Instead rename static.es.js to end in .cjs, change the requiring code to use import(), or remove "type": "module" from D:\febryan\www\mindtrex-executive-microservice\node_modules\@nanoexpress\
middleware-static-serve\package.json.
     at Object.Module._extensions..js (internal/modules/cjs/loader.js:1085:13)
     at Module.load (internal/modules/cjs/loader.js:933:32)
     at Function.Module._load (internal/modules/cjs/loader.js:774:14)
     at Module.require (internal/modules/cjs/loader.js:957:19)
     at Module.Hook._require.Module.require (D:\febryan\www\mindtrex-executive-microservice\node_modules\require-in-the-middle\index.js:80:39)
     at require (internal/modules/cjs/helpers.js:88:18)
     at Object.<anonymous> (D:\febryan\www\mindtrex-executive-microservice\node_modules\@nanoexpress\middleware-schemator\cjs\schemator.cjs.js:3:19)
     at Module._compile (internal/modules/cjs/loader.js:1068:30)
     at Object.Module._extensions..js (internal/modules/cjs/loader.js:1097:10)
     at Module.load (internal/modules/cjs/loader.js:933:32) {
   code: 'ERR_REQUIRE_ESM'
 }

Expected behavior/code

not getting error exception ERR_REQUIRE_ESM.

Environment

Possible Solution

Pull Request #23

Additional context/Screenshots

image image

Note

dalisoft commented 3 years ago

Closed on #23

torbjorn-kvist commented 3 years ago

This seems to break on debian (linux),

file:///home/user/dev/backend/node_modules/@nanoexpress/middleware-schemator/schemator.es.js:46
      staticServe(swaggerUiDist.absolutePath())
      ^

TypeError: staticServe is not a function

As const staticServe = import returns a promise that need to be handle in functionExports.define for schemator.es.js. @game5413 was this only tested on a Windows machine with package.json set to "type": "module" or?

game5413 commented 3 years ago

This seems to break on debian (linux),

file:///home/user/dev/backend/node_modules/@nanoexpress/middleware-schemator/schemator.es.js:46
      staticServe(swaggerUiDist.absolutePath())
      ^

TypeError: staticServe is not a function

As const staticServe = import returns a promise that need to be handle in functionExports.define for schemator.es.js. @game5413 was this only tested on a Windows machine with package.json set to "type": "module" or?

i think because i'm using dynamic import when importing the module the return from import was a promise, i try fix the error using Promise chain like

staticServe.then(
      module => module.default(swaggerUiDist.absolutePath())
    )
      .then(
        result => app.get(
          '/swagger-ui-dist/:file',
          result
        )
      );

not throwing the error, but still i got no response with dist directory before i'm make this change. Maybe i'll rollback this commit later if still not return, but the cjs method will waiting another fix, because import path not compatible.

torbjorn-kvist commented 3 years ago

Yeah, noticed that it was a promised. Promise chain or maybe async/await?
What fix is the cjs waiting for?

Please tag me if you want me to test on a linux installation or such :) Using a version(3.0.5), before the change and that seems to work on my setup for now.

game5413 commented 3 years ago

Yeah, noticed that it was a promised. Promise chain or maybe async/await? What fix is the cjs waiting for?

Please tag me if you want me to test on a linux installation or such :) Using a version(3.0.5), before the change and that seems to work on my setup for now.

Before this change, staticServe import was from @nanoexpress/middleware-static-serve that reference into es module, this change purpose was to determine what import path used when building using rollup for cjs version. Currently i'm using examples folder on packages schemator for testing on my machine and yes i'm using Windows, before and after this change, swagger ui still load for unknown reason like below. Can you share what version you share at your env ? the examples one using:

nanoexpress: ^4.0.0 @nanoexpress/middleware-body-parser: ^1.2.2 @nanoexpress/middleware-schemator: local build and another version before this change

image

torbjorn-kvist commented 3 years ago

I'm using

  "dependencies": {
    "@nanoexpress/middleware-body-parser": "^1.2.2",
    "@nanoexpress/middleware-schemator": "3.0.5",
    "nanoexpress": "^5.0.7",
  }

  node version: v16.6.0

Swagger loads for me on localhost:[port]/swagger using above versions

game5413 commented 3 years ago

I'm using

  "dependencies": {
    "@nanoexpress/middleware-body-parser": "^1.2.2",
    "@nanoexpress/middleware-schemator": "3.0.5",
    "nanoexpress": "^5.0.7",
  }

  node version: v16.6.0

Swagger loads for me on localhost:[port]/swagger using above versions

Try using that version version dependencies, got an error

undefined:5
    <meta charset="UTF-8"><title>${(config && config.title) || 'Schemator'}</title><link rel="stylesheet" type="text/css" href="./swagger-ui-dist/swagger-ui.css" ><link rel="icon" type="image/png" href="./swagger-ui-dist/favicon-32x32.png" 
sizes="32x32" /><link rel="icon" type="image/png" href="./swagger-ui-dist/favicon-16x16.png" sizes="16x16" /><style>html{box-sizing:border-box;overflow:-moz-scrollbars-vertical;overflow-y:scroll}*,:after,:before{box-sizing:inherit}body{margin:0;background:#fafafa}</style></head><body><div id="swagger-ui"></div><script src="./swagger-ui-dist/swagger-ui-bundle.js"> </script><script src="./swagger-ui-dist/swagger-ui-standalone-preset.js"></script><script>window.onload=function(){const o=SwaggerUIBundle({url:window.location.protocol+"//"+window.location.host+"${config.exposePath}",dom_id:"#swagger-ui",deepLinking:!0,presets:[SwaggerUIBundle.presets.apis,SwaggerUIStandalonePreset],plugins:[SwaggerUIBundle.plugins.DownloadUrl],layout:"StandaloneLayout"});window.ui=o};</script></body></html>`)
                                    ^

ReferenceError: config is not defined
    at eval (eval at compileRoute (D:\febryan\nanoexpress-middleware\packages\schemator\examples\node_modules\nanoexpress\cjs\nanoexpress.js:1581:16), <anonymous>:5:37)
    at D:\febryan\nanoexpress-middleware\packages\schemator\examples\node_modules\nanoexpress\cjs\nanoexpress.js:1961:27

using example code

import bodyParser from '@nanoexpress/middleware-body-parser';
import schemator from '@nanoexpress/middleware-schemator';
import nanoexpress from 'nanoexpress';
import path from 'path';

const app = nanoexpress({
  jsonSpaces: 2
});

const schematorInstance = schemator({ swaggerPath: path.resolve('./swagger.json') });
app.define(schematorInstance.define);

app.use(bodyParser());

app.get(
  '/',
  // Here any body-parser, form-data logic (all preprocess middlewares)
  schematorInstance.load({ method: 'get', attach: '/', path: path.resolve('./docs.yml') }),
  async () => ({ status: 'success' })
);
app.post(
  '/',
  // Here any body-parser, form-data logic (all preprocess middlewares)
  schematorInstance.load({ method: 'post', attach: '/', path: path.resolve('./docs.yml') }),
  async (req) => ({ status: 'success', data: req.body })
);

app.listen(4000);
game5413 commented 3 years ago

already test using windows and docker toolbox still got an error like above, can you share your code ? if still not working using your code will try your env for testing @torbjorn-kvist

image

torbjorn-kvist commented 3 years ago

already test using windows and docker toolbox still got an error like above, can you share your code ? if still not working using your code will try your env for testing @torbjorn-kvist

image

Strange, tried to clear all my local cache and removed node_modules. After doing that I seem the be getting the same error on v3.0.5.

It seems that config does not exist in the scope of the return async. https://github.com/nanoexpress/middlewares/blob/9bc598d6db7f7f3e227427db6eefdf77ac167f81/packages/schemator/methods/render.js#L16-L20

Which seems kinda strange, somehow the config does not exist in the scope anymore but works if I add {} around the return async as below:

 return async (req, res) => {
     res.end(...) 
 }
game5413 commented 3 years ago

already test using windows and docker toolbox still got an error like above, can you share your code ? if still not working using your code will try your env for testing @torbjorn-kvist image

Strange, tried to clear all my local cache and removed node_modules. After doing that I seem the be getting the same error on v3.0.5.

It seems that config does not exist in the scope of the return async. https://github.com/nanoexpress/middlewares/blob/9bc598d6db7f7f3e227427db6eefdf77ac167f81/packages/schemator/methods/render.js#L16-L20

Which seems kinda strange, somehow the config does not exist in the scope anymore but works if I add {} around the return async as below:

 return async (req, res) => {
     res.end(...) 
 }

Yeah, already tried with adding {} before and not getting an error, but in my case still take time to load the content. tried with v3.0.5 and v3.0.6. We can assume that config was broke from or before v3.0.5 version.

image

and after a while, tried refresh and see what holding the content show, the swagger file always pending without a timeout

image

@torbjorn-kvist

game5413 commented 3 years ago

i found the problem for not showing content if switched to live mode, filepath got an double directory and return not found, but the catch was set to null so the middleware think error not happen. I don't know this only happen on windows or not, can you check it ? @torbjorn-kvist

url:  /swagger-ui-dist/swagger-ui-standalone-preset.js
filePath:  D:\febryan\nanoexpress-middleware\packages\schemator\examples\node_modules\swagger-ui-dist/swagger-ui-dist/swagger-ui-standalone-preset.js
stat.error:  [Error: ENOENT: no such file or directory, stat 'D:\febryan\nanoexpress-middleware\packages\schemator\examples\node_modules\swagger-ui-dist\swagger-ui-dist\swagger-ui-standalone-preset.js'] {
  errno: -4058,
  code: 'ENOENT',
  syscall: 'stat',
  path: 'D:\\febryan\\nanoexpress-middleware\\packages\\schemator\\examples\\node_modules\\swagger-ui-dist\\swagger-ui-dist\\swagger-ui-standalone-preset.js'
}

edit: for mode cached already found the problem with along the solution, but need cross check from another environment beside Windows