rollup.js: crypto.getRandomValues() not supported - node.js

I am working on an Obsidian plugin that requires bundling using rollup.js. This plugin needs to import inrupt solid libraries that, when imported, are causing the following error:
Error: crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported
at rng (/Users/candide/work/sekund/solid-build-issues/main_rollup.js:16740:10)
at v4 (/Users/candide/work/sekund/solid-build-issues/main_rollup.js:17186:53)
at new Session (/Users/candide/work/sekund/solid-build-issues/main_rollup.js:23526:88)
at Repro.<anonymous> (/Users/candide/work/sekund/solid-build-issues/main_rollup.js:23669:17)
at step (/Users/candide/work/sekund/solid-build-issues/main_rollup.js:160:15)
at Object.next (/Users/candide/work/sekund/solid-build-issues/main_rollup.js:111:11)
at /Users/candide/work/sekund/solid-build-issues/main_rollup.js:83:65
at new Promise (<anonymous>)
at __awaiter (/Users/candide/work/sekund/solid-build-issues/main_rollup.js:65:9)
at Repro.login (/Users/candide/work/sekund/solid-build-issues/main_rollup.js:23664:10)
When debugging the code, it turns out that the crypto constant is not defined. However, at the start of the generated bundle, I can see:
var crypto_1 = require("crypto");
So it looks like my problem basically boils down to rollup redefining global variables when it should not.
Indeed, using the typescript compiler (tsc) on the same source file outputs a perfectly working program.
Here's my rollup config:
import commonjs from "#rollup/plugin-commonjs";
import json from "#rollup/plugin-json";
import { nodeResolve } from "#rollup/plugin-node-resolve";
import typescript from "#rollup/plugin-typescript";
const banner = `/*
THIS IS A GENERATED/BUNDLED FILE BY ROLLUP
if you want to view the source visit the plugins github repository
*/
`;
export default {
input: "src/main.ts",
inlineDynamicImports: true,
output: [
{
file: "main.js",
sourcemap: "inline",
format: "cjs",
exports: "default",
banner,
},
],
external: ["obsidian", "fs", "os", "path"],
plugins: [json(), nodeResolve({ preferBuiltins: true }), commonjs(), typescript({ sourceMap: true })],
};
I created a repro repo at https://github.com/ckemmler/solid-build-issues

man this wrecked my brain for a bit, i managed to find a solution but i don't understand it 100%
please see the solution suggested in this comment https://github.com/uuidjs/uuid/issues/544#issuecomment-740394448
resolved the problem for me

Related

Bundle NPM Package so it has different import paths with Vite and Typescript

How can I bundle my NPM package in a way that I can have different import paths for different parts of the package? I have found webpack approaches, but I am using Vite and TS.
My package looks like this:
- src
- atoms
- molecules
- organism
- index.ts (currently simply imports and exports everything)
Now I can use this currently like this
import { Button } from '#mypackage/library'
How can I do it, so I get this outcome:
import { Button } from '#mypackage/library/atom'
Here is the relevant part of my package.json
{
"entry": "src/index.ts",
"main": "dist/index.cjs.js",
"module": "dist/index.es.js",
"types": "dist/index.d.ts",
"files": [
"dist",
"src"
],
"exports": {
".": {
"import": "./dist/index.es.js",
"require": "./dist/index.cjs.js",
"types": "./dist/index.d.ts"
},
"./package.json": "./package.json",
"./atoms": "./src/atoms/index.ts",
"./molecules": "./src/molecules/index.ts",
"./organisms": "./src/organisms/index.ts",
"./theme": "./src/theme/index.ts"
},
}
Here is my vite.config.ts
export default defineConfig({
build: {
lib: {
entry: path.resolve(__dirname, 'src/index.ts'),
formats: ['es', 'cjs'],
name: '#workdigtital/component-library-react',
fileName: (format) => `index.${format}.js`
},
rollupOptions: {
external: ['react', 'react-dom'],
output: {
globals: {
react: 'React',
'react-dom': 'ReactDOM'
},
exports: 'named'
}
}
},
plugins: [react(), dts({ insertTypesEntry: true })],
resolve: {
alias: {
'#': path.resolve(__dirname, './src')
}
}
});
If I currently try an import like this, inside another project (Laravel+React), in which installed the library.
import { ThemeProvider } from '#workdigital/component-library-react/theme';
I get the following run time error (But no Typescript errors, even IntelliSense is working):
Failed to load url /resources/js/theme/ThemeProvider (resolved id: /resources/js/theme/ThemeProvider). Does the file exist?
My resulting Dist folder looks like this:
You can't have TypeScript exports, this simply won't work. An npm package should have only JS exports.
If you want to be able to selectively import different parts of your package, you must transpile them to different files.
rollup can do it, but it is lots of work, as you will have to set up a separate target for each exported file. Normally you use rollup to create a single bundle, this what this tool is made for.
tsc with a tsconfig.json will be a much better choice in your case. It does this by default, you only need to specify the output directory and it will produce a separate file for each source.
There is an excellent guide on the TypeScript site about packaging TypeScript libraries, you should probably start there.

Vitest alias or inline.deps fail to resolve import error

I am migrating some jest tests over to vitest and some of my tests are failing due to an import issue of an external package dependency in node_modules. Specifically: #package/dependency seems to be an ES Module but shipped in a CommonJS package.
vitest suggests this change to my config:
export default {
test: {
deps: {
inline: [
"#package"
]
}
}
}
Unfortunately, this fix does not work. Previously I resolved this issue with moduleNameMapper in jest where "#package/dependency": "#package/dependency/js" mapped to a valid import. I tried setting alias in both test.alias and resolve.alias, but neither works.
I am using Typescript in this project, and the rest of my test config looks like this:
test: {
globals: true,
environment: "jsdom",
setupFiles: "./src/setupTests.js",
}
// setupTests.js
import {configure} from 'enzyme/build';
import Adapter from 'enzyme-adapter-react-16/build';
configure({ adapter: new Adapter() });
What can I do to get around this? Thanks.

Using rollup/svelte/node-polyfills, import and require function differently

//this works
const homedir = require('os').homedir;
console.log(homedir())
//this throws "Error: 'homedir' is not exported by polyfill-node.os.js ..."
import {homedir} from 'os'
console.log(homedir())
Why would the behavior be different if import can reference both ESM and CJS modules?
Relevant rollup config:
export default (async ()=>({
input: 'app/svelte.ts',
output: {
sourcemap: !production,
format: 'iife', //used for loading up JS in a script tag
file: 'public/build/bundle.js',
},
plugins: [
nodePolyfills(),
svelte({
preprocess: preprocess()
}),
commonjs({
defaultIsModuleExports: true,
transformMixedEsModules: true
}),
css({output: 'bundle.css'}),
typescript(),
alias({
entries: [
{find: /^#pkg\/(.*)/, replacement: 'packages/$1'},
],
}),
resolve({
browser: true,
dedupe: ['svelte'],
}),
!production && serve(),
!production && livereload('public'),
json(),
],
}))()
Rollup plugin order seems to matter, too, because when i shift nodePolyfills() below resolve(), the error changes to Use output.globals to specify browser global variable names corresponding to external modules os (guessing 'os'). I've attempted using the suggested fixes for this including externals and output.globals in rollup config without any success.

Node.js: How to import test files in custom test runner

I'm trying to create my own custom testing framework for learning purpose. Test files are written in following way
import { somemethod } from './some/module'
test(/I click on a button)/, () => {
browser.get("someSelector").should("have.text",somemethod());
});
I user require(file) to load test files. But it throw error SyntaxError: Unexpected token {
for import statement in test file. I'm using node js version 11.15.
If I switch to node v13.14 and define "type": "module" in my package.json then it doesn't let me use require(file) to load a test file or any module in my package.
How can I import tests files considering the user may be importing the modules using import or require?
This answer is very empirical...
Considering that it works using canonical commonjs approach you can try to debug it with newer version of NODE (currently I would use 14). For it, I would suggest you to use a node version manager like NVM so you can switch between node version easily and test that accordling seeing differences between various node installations.
Make a minimal project with npm init with a single dependency, save your index with the .mjs extension and try an import the above dependency. If you are be able to import that dependency with that minimal environment you can blame either your previous node or your configuration or both of them.
At the moment you should only create a small 2 files project to reproduce the problem. It seems your current node does not consider the "type": "module" configuration and runs everything in its classic way.
Regarding your comments....
As far as I know import can be used even in your code, not just at the beginning:
(async () => {
if (somethingIsTrue) {
// import module for side effects
await import('/modules/my-module.js');
}
})();
from https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import
Additionally you can try Webpack with a configuration like:
// webpack.config.js
const nodeExternals = require('webpack-node-externals');
module.exports = {
mode: 'production',
target: 'node',
externals: [nodeExternals()],
entry: {
'build/output': './src/index.js'
},
output: {
path: __dirname,
filename: '[name].bundle.js',
libraryTarget: 'commonjs2'
},
module: {
rules: [
{
test: /\.js$/,
use: {
loader: 'babel-loader',
options: {
presets: [
['env', {
'targets': {
'node': 'current'
}
}]
]
}
}
}]
}
};
With NodeExternals you don't put your node dependencies in the bundle but only your own code. You refer to node_modules for the rest. You might not want that.

"You may need an appropriate loader for this file type", webpack can't parse angular2 file

I'm trying to get a very simple Angular2 app working, with Webpack as a module bundler. I'm following this code, and I copied all the configuration files as they are, only changing file paths. However, when I run npm-start, I get the following error, which I think is a Webpack error:
ERROR in ./hello.js
Module parse failed: /home/marieficid/Documentos/cloud/cloud/hello.js Line 1: Unexpected token
You may need an appropriate loader to handle this file type.
| import {bootstrap} from "angular2/platform/browser";
| import {Component} from "angular2/core";
|
# ./app.ts 2:0-21
As a result, the Angular2 code in my app isn't loaded.
This is my app.ts:
import "./hello.js";
This is hello.js, where the error seems to be (which I take to mean that webpack parsed app.ts just fine):
import {bootstrap} from "angular2/platform/browser";
import {Component} from "angular2/core";
#Component({
selector: 'app',
template: '<div>Hello world</div>'
})
class App{}
bootstrap(App);
And this iswebpack.config.js:
var webpack = require('webpack');
var HtmlWebpackPlugin = require('html-webpack-plugin');
var path = require('path');
module.exports = {
entry: {
'app': './app.ts',
'vendor': './vendor.ts'
},
output: {
path: "./dist",
filename: "bundle.js"
},
plugins: [
new webpack.optimize.CommonsChunkPlugin('vendor', 'vendor.bundle.js'),
new HtmlWebpackPlugin({
inject: false,
template: './index.html'
})
],
resolve: {
extensions: ['', '.ts', '.js']
},
module: {
loaders: [
{ test: /\.ts$/, loader: 'ts-loader' },
],
noParse: [ path.join(__dirname, 'node_modules', 'angular2', 'bundles') ]
},
devServer: {
historyApiFallback: true
}
};
All these files and node_modules are in the same directory.
I have found similar questions online but nothing worked for me. I also didn't install babel because the sample code I'm using as base doesn't use it, but if it's necessary I'm will.
As suggested by #napstablook
Since in your webpack.config.js file you have
resolve: {
extensions: ['', '.ts', '.js']
},
Webpack will try to handle those .js files but it needs a specific loader to do so which is, if I'm not wrong, script-loader.
In your case the solution is as simple as deleting the .js files, or changing their extension to be .ts.
For me this issue occurred when I ran ng test,
please check below points,
Console will list out the files that is causing the error.
Check the html file is correctly mapped from the typescript.
styleUrls file should point to the CSS file not html, this is the mistake I
did.
this error also comes up for me in angular forms when i had patch value set then an extra = sign
ncont.controls[position].patchValue({[cardname]:file}) = file
which is a dumb part on me and angular for not telling me

Resources