Nuxt3 - how to use vite-plugin-wasm - node.js

I'm building a Nuxt3 application where I need to import and use a 3rd party node package which internally is using webassembly.
In my case, the package I need is https://github.com/higumachan/lindera-js
Where do I import the package?
In one of my components, right at the beginning of the <script> tag.
And afterwards I'm using it in one of the methods.
(Note: I removed unnecessary code below)
<template>
...
</template>
<script>
import * as lindera from "lindera-js";
...
methods: {
doTranspile() {
const tokenized= lindera.tokenize(this.input);
console.log(tokenized);
},
},
...
</script>
What is the Problem?
After dev server compiles everything and I reload the page in the browser, I get the following error:
[vite] Internal server error: "ESM integration proposal for Wasm" is not supported currently.
Use vite-plugin-wasm or other community plugins to handle this.
Alternatively, you can use .wasm?init or .wasm?url.
See https://vitejs.dev/guide/features.html#webassembly for more details.
The Question
How can I use the package without problems in Nuxt3? Do I have to use vite-plugin-wasm and if so, how and where to use/import it?
Or is there any other way to use a package which is using webassembly?
I found some similar questions on SO, but not sure if they can be used like this in Nuxt3 as I'm fairly new to Nuxt in general.
How to use embedded Webassembly in Vite?
How to include an WASM npm module in svelte with vite?

Related

How to use an angular module that does not support Universal with an angular/cli app using SSR

Hey everyone I have been building an Angular app that is using Universal with SSR for a while not and every so often I would include a module that would cause the server to fail silently and never knew why, last night I figured out it was because the module I tried to include (ngx-editor) does not support Universal.
Is there a way for me to include a module such as ngx-editor that does not support Universal in my application? Or do I have to find one that supports Universal?
Thanks a lot in advance.
You could try not calling this module's components depending on the platform, e.g. by checking the platform dynamically in your code ( https://angular.io/api/common/isPlatformBrowser)
import {isPlatformBrowser} from "#angular/common";
//...
constructor(#Inject(PLATFORM_ID) private platformId: Object)
{
if(isPlatformBrowser(this.platformId))
{
//call module's methods/components...
}
else { /*server side*/ }
}
You may also need to modify your server module (app.server.module.ts) to not include modules that do not support angular-universal

Sails.js: can't find variable require (react-bootstrap-datetimepicker)

I'm using Sails js and I want to use a nodejs module.
I also use React js.
I want to use react-bootstrap-datetimepicker in my javascript script.
react-bootstrap-datetimepicker
I installed my module with npm install react-bootstrap-datetimepicker
I tried in config/boostrap.js to add this line var DateTimeField = require('react-bootstrap-datetimepicker');, but DateTimeField isn't recognised in my js script.
Uncaught ReferenceError: DateTimeField is not defined
I also tried to add this line directly in my script, but I have this error:
ReferenceError: Can't find variable: require
And also this one in my script: import DateTimeField from "react-bootstrap-datetimepicker";
I have all these errors in the navigator console.
EDIT 1:
I understand what you said, thank you for your answer.
BUT, for example with react-bootstrap, I can use:
var Input = ReactBootstrap.Input;
var ButtonInput = ReactBootstrap.ButtonInput;
There is exactly the same architecture with react-bootstrap-datetimepicker, so I maybe I can do the same?
var DateTimePicker = ... . DateTimePicker
I tried to include like you said, but it doesn't recognise DateTimePicker.
Here is the doc:
Installation :
npm install react-bootstrap-datetimepicker
Then
javascript
var DateTimeField = require('react-bootstrap-datetimepicker');
render: function() {
return <DateTimeField />;
}
See (examples/) for more details.
And in examples/, the line is:
import DateTimeField from "react-bootstrap-datetimepicker";
Ok, first you have to understand the division of server side and client side javascript, even thought you are using the same language, and you can share libraries, bare in mind, that for client side js you need to supply the user browser with the libraries and scripts it needs, so those have to be in the html you serve the user. When you require any module in sails bootstrap or similar, you are loading the script into the server memory, not serving it to the users browser, that means you can use in the server code, but not in client code.
For you use case, you have to download the library code, and put it in your assets/js folder and if you have the script tags in the layout, sails will automatically inject it there for you, but if not or you are using other template engine like jade, just manually add it.
example:
<html>
....
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/<react-version>/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/<react-version>/react-dom.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-bootstrap/<version>/react-bootstrap.min.js">
<script src='/js/react-bootstrap-datetimepicker.min.js'></script>
// The other js files that depend on datetimepicker go here
</html>
Now just to be clear, require is a node.js function, node.js is not the same as javascript, its a piece of software with its own functions, thats why you are getting an error related to it when trying to use it in the browser, there is no require method there, so you can't use it, at least not directly. You can use browserify to sort of emulate the node workflow, where you have a node_modules folder and use require on those, browserify will bundle (search for the modules and merge them) and give you a javascript file that you can then link in your html code. That is more setup work, and unless you really need it, because you have a lot of files, i think is not worth the effort.. lets say for just one file using require.
So i think you were misguided by that github repo, because it says npm-install. Just ignore it (unless you use browsefify like i said) and download the link i gave you above ( the .min.js).
So to sumarize, you issue have nothing to do with sails, just link the library in the html you provide to the user, like any other client side script.

nwjs reactjs, confused about my context. Document is undefined

In my nwjs application i am using React to build my UI. Currently, React is being loaded via a <script> tag in the main file, index.html. index.html has another <script> tag which loads main.js containing code which defines and renders my React components as well as requiring (require()) a few Node modules such as "fs" and "McFly".
This all seems to be working, however when i try using another node module (react-inlinesvg) i get an error, "document is undefined".
Having looked online for help, i have come to the conclusion that React now believes that it is being run on the server? Which is odd, as before i started using the react-inlinesvg module it was happily rendering components using React.render (clientside rendering).
If you need any more context or information then please ask.
It could be that you are rendering on the server side, or also that you are rendering both sides. In the second case you could simple nest the line that is causing you error with:
if (process.env.BROWSER) {
the line causing the error
}
If the error disappears, it means that you are on the server side also!
I hope this helps...
Basically if you code is universal (or isomorphic, if you want...) with this check you can execute the code only on client side, you want to do this to use a particular style-sheet for example:
if (process.env.BROWSER) {
require("../style/main.scss");
}
Naturally if you want to do stuff server-side you can check
if (!process.env.BROWSER) {
}
if any one face this he can solve it in 2 ways:
Solution 1: if you are using nw.js 15 or above try to enable mix context mode:
in your package.json add this flag:
"chromium-args": "--mixed-context"
Solution 2: expose document to the global object using this hack:
global.document = window.document;

Browserifying react with addons to a standalone component, usable by plugins

I am experementing a bit with react and browserify and have these wishes:
I want to bundle all code written by me into a single file
I want to bundle all 3rd party dependencies (react, react-router, lodash etc) into separate files, one for each lib, to maximize caching possibilities
I have managed to do the things described above but I ran into this specific situation:
In some places of my code I want to use react with addons and as such require it like this: var React = require('react/addons). I don't do this in all parts of my code and it is not done in 3rd party dependencies such as react-router. This seems to create a conflict. Either the browserified bundle will only be available through var React = require('react/addons) which breaks 3rd party dependencies, or I will have to bundle react both with or without addons which menas that react is bundled and downloaded twice.
I tried to use aliasify and make react an alias for react/addons but I couldn't make it work. Should this be possible?
Another acceptable solution would be to bundle just the addons in a separate bundle and through that make both react and react/addons available through calls to require. Is any of this possible?
Addition
As a comment to the first comment by BrandonTilley, this is not just applicable to React and addons. Lodash also comes with a number of different distributions and I would like to be able to choose the version to use in my webapp in this case as well.
Notice that what you want to achieve is documented here: Browserify partitionning
I'm packaging my app in 2 parts: appLibs.js and app.js.
I've done this for caching too but I choose to put all the code that does not change often in a single bundle instead of splitting it like you want, but you can use the same trick.
Here's the code that might interest you:
var libs = [
"react",
"react/addons", // See why: https://github.com/substack/node-browserify/issues/1161
... other libs
];
gulp.task('browserify-libs', function () {
var b = browserify(...);
libs.forEach(function(lib) {
b.require(lib);
});
return b.bundle().......
});
gulp.task('browserify',['browserify-libs'],function () {
var b = browserify(...);
libs.forEach(function(lib) {
b.external(lib);
});
return b.bundle().......
});
This way, React is only bundled once in appLibs.js and can be required inside app.js using both react and react/addons
If you really want to bundle your libs in separate files, bundle then with b.require("myLib"), but in this case be sure to check that the libraries do not have direct dependencies. If a lib to bundle has a dependency in React, this means that lib will be packaged in the bundle, potentially leading to multiple bundles having React inside them (and making weird failures at runtime). The library should rather use peerDependencies so that b.require does not try to package these dependencies
Sounds like the perfect use case for factor-bundle.
From the browserify handbook:
factor-bundle splits browserify output into multiple bundle targets based on entry-point. For each entry-point, an entry-specific output file is built. Files that are needed by two or more of the entry files get factored out into a common bundle.
Thanks for all suggestions but the solution I have chosen is a "shim" if that is the correct term. Looks like this:
Browserify react/addons into it's own file
Create my own file (called shim) only containing this: module.exports = require('react/addons');
Browserify my shim and use the expose option, exposing it as react
Now, either if react or react/addons is required I get react/addons

Meteor.js: How do you require or link one javascript file in another on the client and the server?

1) In node on the backend to link one javascript file to another we use the require statement and module.exports.
This allows us to create modules of code and link them together.
How do the same thing in Meteor?
2) On the front end, in Meteor is I want to access a code from another front end javascript file, I have to use globals. Is there a better way to do this, so I can require one javascript file in another file? I think something like browserify does this but I am not sure how to integrate this with Meteor.
Basically if on the client I have one file
browserifyTest.coffee
test = () ->
alert 'Hello'
I want to be able to access this test function in another file
test.coffee
Template.profileEdit.rendered = ->
$ ->
setPaddingIfMenuOpen()
test()
How can I do this in Meteor without using globals?
Meteor wraps all the code in a module (function(){...your code...})() for every file we create. If you want to export something out of your js file (module), make it a global. i.e don't use var with the variable name you want to export and it'll be accessible in all files which get included after this module. Keep in mind the order in which meteor includes js files http://docs.meteor.com/#structuringyourapp
I don't think you can do this without using globals. Meteor wraps code in js files in SEF (self executing function) expressions, and exports api is available for packages only. What problem do you exactly have with globals? I've worked with fairly large Meteor projects and while using a global object to keep my global helpers namespaces, I never had any issues with this approach of accessing functions/data from one file in other files.
You can use a local package, which is just like a normal Meteor package but used only in your app.
If the package proves to be useful in other apps, you may even publish it on atmosphere.
I suggest you read the WIP section "Writing Packages" of the Meteor docs, but expect breaking changes in coming weeks as Meteor 0.9 will include the final Package API, which is going to be slightly different.
http://docs.meteor.com/#writingpackages
Basically, you need to create a package directory (my-package) and put it under /packages.
Then you need a package description file which needs to be named package.js at the root of your package.
/packages/my-package/package.js
Package.describe({
summary:"Provides test"
});
Package.on_use(function(api){
api.use(["underscore","jquery"],"client");
api.add_files("client/lib/test.js","client");
// api.export is what you've been looking for all along !
api.export("Test","client");
});
Usually I try to mimic the Meteor application structure in my package so that's why I'd put test.js under my-package/client/lib/test.js : it's a utility function residing in the client.
/packages/my-package/client/lib/test.js
Test={
test:function(){
alert("Hello !");
}
};
Another package convention is to declare a package-global object containing everything public and then exporting this single object so the app can access it.
The variables you export NEED to be package-global so don't forget to remove the var keyword when declaring them : package scope is just like regular meteor app scope.
Last but not least, don't forget to meteor add your package :
meteor add my-package
And you will be able to use Test.test in the client without polluting the global namespace.
EDIT due to second question posted in the comments.
Suppose now you want to use NPM modules in your package.
I'll use momentjs as an example because it's simple yet interesting enough.
First you need to call Npm.depends in package.js, we'll depend on the latest version of momentjs :
/packages/my-moment-package/package.js
Package.describe({
summary:"Yet another moment packaged for Meteor"
});
Npm.depends({
"moment":"2.7.0"
});
Package.on_use(function(api){
api.add_files("server/lib/moment.js");
api.export("moment","server");
});
Then you can use Npm.require in your server side code just like this :
/packages/my-moment-package/server/moment.js
moment=Npm.require("moment");
A real moment package would also export moment in the client by loading the client side version of momentjs.
You can use the atmosphere npm package http://atmospherejs.com/package/npm which lets you use directly NPM packages in your server code without the need of wrapping them in a Meteor package first.
Of course if a specific NPM package has been converted to Meteor and is well supported on atmosphere you should use it.

Resources