Browserify cannot find module has been installed from local filesystem - javascript

I have several JavaScript files that requires several modules that are managed by NPM. I am trying to bundle these files together with Browserify. However, I am getting the following error:
Cannot find module 'fairychess-web' from '...App.js'
(the full path has been elided).
This module is required in the following area of App.js:
exports.__esModule = true;
var jsx_runtime_1 = require("react/jsx-runtime");
var react_1 = require("react");
require("./App.css");
var fairychess_web_1 = __importStar(require("fairychess-web"));
var chess_lib_1 = require("./chess_lib");
var net_lib_1 = require("./net_lib");
My dependencies are in my package.json file as follows:
"dependencies": {
"#types/node": "^18.11.11",
"#types/react": "^18.0.26",
"fairychess-web": "file:../fairychess-web/pkg",
"http": "^0.0.1-security",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"ws": "^8.11.0"
}
As you can see, the offending fairychess-web module is defined locally rather than on the NPM registry. I think this is why Browserify is having trouble finding the module, because I'm not receiving any error messages about the previous imports of libraries downloaded from NPM, but I have no idea as to how to solve the problem.
A few notes that may be relevant
App.js and the rest of my files, like chess_lib and net_lib, were created though tsc run on TypeScript files.
The fairychess-web module is a Rust package that was compiled to WASM with wasm-bindgen. This created a TypeScript wrapper file through which I am interfacing the Rust code and my Typescript code.
This code was originally built on create-react-app. At that time there were no problems importing the local module, this problem only arose when I decided to manually build the project.

Related

How to import Kotlin/JS generated module in a separate npm-based project

I would like to create a js library with Kotlin Multiplatform (an example of which is this project, where we have a webscocket server and a js client) which I will then build as a npm package and import in my Vue project (could be any other framework).
what I managed to do with chat project is:
build js sources with ./gradlew build
publish that via yarn publish (setting up remote registry url ofc)
add published package to package.json with (needed to update project name to #chat/client by hand in the generated package.json):
{
"name": "#chat/client",
"version": "0.0.1",
"private": false,
"workspaces": [
"packages/chat-frontend",
"packages/chat-frontend-test",
"packages_imported/kotlin/1.6.21",
"packages_imported/ktor-ktor-client-core-js-ir/2.0.0",
"packages_imported/kotlin-test-js-runner/1.6.21"
],
"resolutions": {},
"devDependencies": {},
"dependencies": {},
"peerDependencies": {},
"optionalDependencies": {},
"bundledDependencies": []
}
added #JsExport annotation on writeMessage in src/frontendMain/kotlin/main.kt
what I didn't manage is (in my Vue project):
import writeMessage, I exported in .kt file (it's visible in source, not exported though)
import anything via import * from '#chat/client'
or any other folder along '#chat/client/*'
use the generated files in any other way
The generated package structure is very odd:
~ ls build/js/*
build/js/package.json build/js/yarn.lock
build/js/node_modules:
... (npm dependencies from Kotlin/JS module)
build/js/packages:
chat-frontend chat-frontend-test
build/js/packages_imported:
... (Kotlin/JS dependencies)
~ ls build/js/packages/chat-frontend/*
build/js/packages/chat-frontend/package.json build/js/packages/chat-frontend/webpack.config.js
build/js/packages/chat-frontend/kotlin:
chat-frontend chat-frontend.js chat-frontend.js.map chat-frontend.meta.js
(chat-frontend contains package dir tree and a file frontend.kjsm)
build/js/packages/chat-frontend/kotlin-dce:
chat-frontend.js
ktor-*.js
kotlinx-*.js
... (compiler output ???)
build/js/packages/chat-frontend/node_modules:
... (webpack cli and dev-server files)
Do you have any clues, tips or an example project which does that? I've processed whole section of Kotlin/JS docs but there is no information on how to import Kotlin generated .js files in a js/ts project.
EDIT:
I've updated my fork of ktor-samples with Kotlin/JS build files: build-js folder and src/backendMain/resources/chat.js. Here's the link to chat folder of the fork project
I will try to help
Kotlin/JS has 2 kinds of compiler: legacy and IR. #JsExport affects only IR compiler. But from kotlin-dce folder, you use legacy compiler backend. In IR compiler, DCE (dead code elimination) is included into compiler and there is no folder kotlin-dce. You can change compiler kind in gradle.properties with kotlin.js.compiler=ir|legacy.
When you build project with IR, packages/*/kotlin will fully contain your library (similar with legacy's kotlin-dce)
Then you need to prepare appropriate package.json file with name and main fields (task :publicPackageJson could help with that, but check, if it is ok for your case)
Now in Kotlin/JS export works with packages. It means, that if you export io.ktor.samples.chat.frontend.writeMessage, it will be exported as io.ktor.samples.chat.frontend.writeMessage in js. So to import it, you need import io and then find necessary declarations.
import { io } from '#chat/client`
io.ktor.samples.chat.frontend.writeMessage("hello")
In the case of classical (non-IR) js backend usage and you use only non-private NPM dependencies then the only thing that you need is to compile your Kotlin/js library (via :compileKotlinJs task), generate package.json for your library (via :publicPackageJson) and your package could be published to NPM or another private repository (by yarn publish).
After publication, you will have the ability to set your library as a dependency in any js project. (Note that the name and version of your library will be placed inside package.json (generated by :publicPackageJson task)).
Also, you can check this discussion. Hope it will help you.

dotenv process.env variable undefined in globally installed custom CLI tool

I'm migrating one of my CLI tools over to a global installation so that it can be installed globally and used anywhere on my system. Most of my src files include require('dotenv').config() at the top of them, but for some reason the env is undefined now that it's installed globally.
What am I missing?
My package JSON looks like:
{
"name": "scoop",
"version": "1.9.0",
"main": "bin/scoop.js",
"dependencies": {
"axios": "0.20.0",
"cli-spinners": "2.4.0",
"commander": "6.1.0",
"dotenv": "8.2.0",
"log-symbols": "4.0.0",
"ora": "5.1.0",
"readline": "1.3.0"
},
"bin": {
"scoop": "./bin/scoop.js"
}
}
bin/scoop.js then contains the following at the top:
#!/usr/bin/env node
require('dotenv').config();
const forms = require('../src/utils/LocateForms');
...
And I'm loading in additional JS src files that are exported, I've got an .env in my project my my custom variables just come up as undefined now?
I think it's expected behaviour.
The default path value for dotenv is Default: path.resolve(process.cwd(), '.env') according to the GitHub readme.
Now process.cwd changes depending upon from where you execute the executable file.
For example if u start node /a/b/c.js then the cwd would be /a/b and if you start it from node /a/b/d/c.js the cwd would be /a/b/d.
So, in order to get the the .env file that you want either you have to store the .env file in a common area like ~/.yourenv like most other executables do(think .bashrc).
Or, you can try to get the installation folder and get the .env file using an absolute path.
For example you can try to import npm and get the prefix to find out the installation folder.
var npm = require("npm")
npm.load({}, function (er) {
if (er) return handleError(er)
console.log(npm.get('prefix'));
})
Or, you can use some package like https://www.npmjs.com/package/get-installed-path

Can't understand importing node modules

I'm very new to web development. I'll try to make the question short. Im trying to use a javascript library called euclid.ts. Its page tells you this:
Instructions to import euclid.ts
So this i what i did:
First I ran the command. Then in my html file, called index.html I import a script file called sketch.js
<body>
<script type="module" src="sketch.js"></script>
</body>
Then in my sketch.js file i have this line right at the top:
import {Point, Line} from '#mathigon/euclid'
The problem is, when I open index.html in the browser I get this error:
Uncaught TypeError: Error solving the module “#flatten-js/core”.
Mode specifiers must start with “./”, “../” or “/”.
I can't understand what I'm doing wrong (and how is the browser supposed to know which file to import if I don't even specify the file in the import line)
One option for compiling/bundling is via "webpack". https://webpack.js.org/guides/getting-started/
If you setup a folder like so:
/project
package.json
sketch.js
package.json
{
"dependencies": {
"#mathigon/euclid": "^0.6.9",
"webpack": "^5.20.1",
"webpack-cli": "^4.5.0"
}
}
sketch.js
import { Point, Line } from '#mathigon/euclid'
console.log ("sketch")
and then run either npm install or yarn install
and then run ./node_modules/.bin/webpack ./sketch.js
you can generate a bundle that includes #mathingo/euclid at dist/sketch.js
Afterwards, the script tag could look like:
<script src="dist/sketch.js"></script>
You need some way of resolving the packages before they go into browser. Browser doesn't not know how to resolve the dependencies for the package '#mathigon/euclid'. Code editors on the other hand can resolve the dependencies. The error that you see would be an error for a package that '#mathigon/euclid' depends upon.
So the actual sketch.js which runs in the browser should be packaged and should be the file with code from '#mathigon/euclid' and all it's dependencies.
You can look at webpack-cli for an easy way to generate the bundled sketch.js https://www.npmjs.com/package/webpack-cli
After installing cli i believe you could do webpack-cli build --entry sketch.js (Not tested)

What is the right way to create separate npm modules and use them locally

I created a React Native component which lives in a different folder with its own package.json file, and I want to use it in another project
MyComponent is located in Workspace/MyComponent and as a few dependencies in package.json
"dependencies": {
"react-navigation": "^1.0.0-beta.11"
},
"peerDependencies": {
"react": "16.0.0-alpha.12",
"react-native": "0.45.1"
},
"devDependencies": {
"react": "16.0.0-alpha.12",
"react-native": "0.45.1"
}
I am currently in the development of MyComponent so I have run npm install in the repo, there is a node_modules folder.
My have linked MyComponent with MyApp which is located in Workspace/MyApp, using npm link
Although, when I run MyApp and try to use MyComponent, it complains about duplicated declaration, because react is in both MyComponent and MyApp, and they are linked.
If I remove the node_modules folder from MyComponent, react-navigation complains about react not defined.
In the ReactJS world, webpack for example allow to set the root with the preferred node_modules folder which is great.
module.exports = {
...
resolve: {
root: path.resolve(__dirname, 'node_modules'),
}
...
}
I wish to do something similar so I don't have duplicated modules and can debug MyComponent in MyApp locally without reinstalling MyComponent for every single change. What is the best approach for me to achieve this?
Thanks
I found a solution to my question, and it's called whackage
https://github.com/FormidableLabs/whackage
If this is something that will eventually be put in its own repo and then will be installed like any other component, I would probably just build it in the node_modules directory of the parent project. That would prevent you from having to run npm install for every little change.
You can also declare a dependency on a local file and then npm will install it in node_modules
"dependencies": {
"my-component": "file:app/components/my-component",
}
So I have a component that I've built within my project that is referenced in my package.json file. When I run npm install this component is installed in the node_modules folder. That could help with the duplicate library declarations but it wouldn't solve the repeated use of npm install
Update: I just learned that npm 5 doesn't copy the files over to the node_modules folder. It now creates a symlink (basically, a virtual directory that points to the real one) to the code in your project.
This means you will not have to run npm install each time you change your code so it will likely be the best solution for you.

How to compile all dependencies with browserify?

I am trying to learn how to use browserify so I can compile all my dependencies to one file. All the dependencies are being pulled in with NPM through updating a package.json. For example, I want to create a file with browserify that consists of the compiled javascript from this json file.
"dependencies": {
"highcharts": "0.0.11",
"bootstrap": "3.1.0"
}
I would like to do this on the fly and have it automatically pull from this json file.
You need to require the dependencies in whatever module you need them. For example, if one of your dependencies is Lodash, you'll require it where you use it:
var lodash = require('lodash');
module.exports = function() {
// do something with lodash in here if you want
};
The purpose of using something like browserify, webpack, etc., is that you specifically don't compile everything into a "global dependency bundle", as this subverts the modularization that those libraries (browserify, webpack) are meant to impose.

Categories