How to use 'discord.js' module in SvelteKit? "require is not defined" error occurrs - ecmascript-6

I'm trying to use discord.js module to develop a Discord bot in SvelteKit.
In the Discord official example, "discord.js" can be used with following code,
const { Client, GatewayIntentBits } = require('discord.js');
const client = new Client({ intents: [GatewayIntentBits.Guilds] });
However, "require is not defined" in SvelteKit as only import is valid syntax with Vite.
Then, how can I use discord.js module in SvelteKit?
Env:
SvelteKit (with TypeScript) version: latest version on August 23, 2022 ("svelte": "^3.44.0",)
Default settings used (e.g. svelte.config.js, tsconfig.json)
discord.js version: 14
What I have done:
Change the require to import => "Failed to fetch dynamically imported module"
Install discord.js with devDependencies
Try using trick as shown below => Module "module" has been externalized for browser compatibility. Cannot access "module.createRequire" in client code.
import { createRequire } from 'module';
const require = createRequire(import.meta.url);
const { Client, GatewayIntentBits } = require('discord.js');
const client = new Client({ intents: [GatewayIntentBits.Guilds] });
Similar quetions I found:
'require' is not defined - Sveltekit with typescript
require is not defined
How can i import thing in js ? (discord.js)

This probably only runs on an endpoint (i.e. on the server).
Make sure the import statement has the correct form:
import { REST, Routes } from 'discord.js';
The vite.config.js apparently needs to be adjusted because the package or one of its dependencies uses the BigInt data type which is only available in newer versions of JS:
const config = {
plugins: [sveltekit()],
build: {
target: ['es2020'],
},
optimizeDeps: { esbuildOptions: { target: 'es2020' } },
}

Related

Vue - i18n custom translations

I have VUE app with vue-i18n plugin.
I would like to load 'custom path' for translations when app is loaded.
The app is not loading the translations? What am I doing wrong?
File: i18n/index.js
/* eslint-disable */
import { createI18n } from "vue-i18n";
import Message from "#/localization/MyCity/en.json"
const i18n = createI18n({
// default locale
locale: "en",
// translations
messages: Message
});
export default i18n;
File: main.ts
import i18n from "./i18n";
const app = createApp(App).use(i18n)
app.mount("#app");
I tried the code above and the translations are not loading. Do you have any suggestions? This even might be the wrong approach to this problem. Do you have any other suggestion.
Topic 2:
Later on I will try and make dynamic translations based on deployment. I would like to make it fast and simple so I was thinking creating .env file with variable MY_CITY_NAME and do it like this import Message from "#/localization/${MY_CITY_NAME}/en.json".
I guess your problem might be that you are not specifying language of your Messages object.
Try this:
const i18n = createI18n({
...
messages: {
en: Message
}
});

Is there any way of conecting atoti cube with ActiveUI frontend?

We are trying to connect an atoti cube the same way that is on env.js on the Active UI frontend.
window.env = {
contentServerVersion: "5.11.x",
contentServerUrl: "https://activepivot-ranch.activeviam.com:5110",
// WARNING: Changing the keys of activePivotServers will break previously saved widgets and dashboards.
// If you must do it, then you also need to update each one's serverKey attribute on your content server.
activePivotServers: {
// You can connect to as many servers as needed.
// In practice most projects only need one.
"Ranch 5.11": {
url: "https://activepivot-ranch.activeviam.com:5110",
version: "5.11.1",
},
"Ranch 5.10": {
url: "https://activepivot-ranch.activeviam.com:5100",
version: "5.10.0",
},
"Ranch 5.9": {
url: "https://activepivot-ranch.activeviam.com:5900",
version: "5.9.4",
},
"my-server": {
url: "https://localhost:9090",
version: "5.10.x",
}
},
};
but when we launch the frontend we are just give this error: 404: The resource at http://localhost:9090/atoti/pivot/rest/v5/ping was not found.
The URL in your env.js is probably not correct. You can find the correct one by running the following in your notebook:
session.link()
Let's call what it returns my-url.
Then your env.js should look like this:
window.env = {
contentServerVersion: "5.10",
contentServerUrl: my-url,
activePivotServers: {
"my-server": {
url: my-url,
version: "5.10",
},
},
};
You might also have to change your version attribute. It depends on your atoti version, as follows:
atoti 0.6.x => version = "5.11.0"
atoti 0.5.x => version = "5.10.0"
atoti 0.2.x, 0.3.x, 0.4.x => version = "5.9.0"
earlier => version = "5.8.0"

NextJs Webpack asset/source returns JSON as a string

Looking for some help to understand what is going on here.
The Problem
We are using a translation service that requires creating JSON resource files of copy, and within these resource files, we need to add some specific keys that the service understands so it knows what should and should not be translated.
To do this as simple as possible I want to import JSON files into my code without them being tree shaken and minified. I just need the plain JSON file included in my bundle as a JSON object.
The Solution - or so I thought
The developers at the translation service have instructed me to create a webpack rule with a type of assets/source to prevent tree shaking and modification.
This almost works but the strange thing is that the JSON gets added to the bundle as a string like so
module.exports = "{\n \"sl_translate\": \"sl_all\",\n \"title\": \"Page Title\",\n \"subtitle\": \"Page Subtitle\"\n}\n";
This of course means that when I try and reference the JSON values in my JSX it fails.
Test Repo
https://github.com/lukehillonline/nextjs-json-demo
NextJs 12
Webpack 5
SSR
Steps To Reproduce
Download the test repo and install packages
Run yarn build and wait for it to complete
Open /.next/server/pages/index.js to see the SSR page
On line 62 you'll find the JSON object as a string
Open .next/static/chunks/pages/index-{HASH}.js to see the Client Side page
If you format the code you'll find the JSON object as a string on line 39
Help!
If anyone can help me understand what is going wrong or how I can improve the webpack rule to return a JSON object rather than a string that would be a massive help.
Cheers!
The Code
next.config.js
module.exports = {
trailingSlash: true,
productionBrowserSourceMaps: true,
webpack: function (config) {
config.module.rules.push({
test: /\.content.json$/,
type: "asset/source",
});
return config;
},
};
Title.content.json
{
"sl_translate": "sl_all",
"title": "Page Title",
"subtitle": "Page Subtitle"
}
Title.jsx
import content from "./Title.content.json";
export function Title() {
return <h1>{content.title}</h1>;
}
pages/index.js
import { Title } from "../components/Title/Title";
function Home({ dummytext }) {
return (
<div>
<Title />
<p>{dummytext}</p>
</div>
);
}
export const getServerSideProps = async () => {
const dummytext = "So we can activate SSR";
return {
props: {
dummytext,
},
};
};
export default Home;

How do I create a "fat" js file with rollup using esm?

I have the following code..
// ui.js (generated by rollup
import Vue from 'vue';
import VueRouter from 'vue-router';
(()=>{
console.log("Wow it actually works");
Vue.use(VueRouter);
const routes = [
{
path: '/',
component: Viewport
}
];
const router = new VueRouter({
mode: "history",
routes: routes
});
window.app = new Vue({ router });
window.app.$mount('#jg-app');
})();
<script src="ui.js" type="module"> </script>
The problem is when I run this I get...
Uncaught TypeError: Failed to resolve module specifier "vue". Relative references must start with either "/", "./", or "../".
This leads me to believe I need a "fat" js that includes dependencies.
I also want to keep everything in es6 modules and avoid introducing say babel.
Is there a way to do this using rollup?
Update
Tried this...
import Vue from "./vue";
But then I get...
Error: Could not resolve './vue' from src/index.js
As far as I can tell this is not possible. I instead had to move the import from the ui project to the server project and create a static js file that looked like this...
//client
import Vue from "./vue"
let app = new Vue(...);
app.$mount('#jg-app');
and import the esm.browser version
// server
app.use('/vue', express.static(__dirname + '/node_modules/vue/dist/vue.esm.browser.js'));
// template
script(src="/main.js" type="module")
Now Vue is working, however, dependencies like Vue-Router appear to not have this es.browser style file.
This is not a solution, it's a workaround
The below rollup config is not esm, it's just a way to create a bundle with dependencies included.
You get one minified browser-compatible JS file.
Here's my working example rollup.config.js (you should replace input: 'src/index.js' with your web app entry point and output.file with a location for the generated bundle):
import resolve from 'rollup-plugin-node-resolve';
import commonjs from 'rollup-plugin-commonjs';
import builtins from 'rollup-plugin-node-builtins';
import babel from 'rollup-plugin-babel';
import visualizer from 'rollup-plugin-visualizer';
import { terser } from "rollup-plugin-terser";
const browserPlugins = [
resolve({browser: true}), // so Rollup can properly resolve cuid
babel({
exclude: 'node_modules/**',
babelrc: false,
presets: ['es2015-rollup'],
}),
// builtins(),
commonjs(),
visualizer(),
terser(),
]
export default [
// browser-friendly UMD build
{
// external: Object.keys(globals),
input: 'src/index.js',
output: {
name: 'thinflux',
file: './dist/browser/thinflux.min.js',
format: 'umd'
},
plugins: browserPlugins,
}
];
One more thing: express should statically serve the output.file path, not your source files

How to import a JSON file in ECMAScript 6?

How can I access a JSON file in ECMAScript 6?
The following doesn't work:
import config from '../config.json'
This works fine if I try to import a JavaScript file.
https://www.stefanjudis.com/snippets/how-to-import-json-files-in-es-modules-node-js/
ES modules are still reasonably new in Node.js land (they're stable since Node 14). Modules come with a built-in module system, and features such as top-level await.
I read an informative post on ES modules by Pawel Grzybek and learned that you can't import JSON files in ES modules today.
import info from `./package.json` assert { type: `json` };
const { default: info } = await import("./package.json", {
assert: {
type: "json",
},
});
That's a real bummer because I'm pretty used to doing require calls such as const data = require('./some-file.json') in Node.js.
But can you use import assertions in Node.js today?
At the time of writing, the current Node.js LTS (v18.12) still marks import assertions as experimental.
This post explains ways to deal with JSON in ES modules if you don't want to use the experimental feature yet.
Option 1: Read and parse JSON files yourself
The Node.js documentation advises to use the fs module and do the work of reading the files and parsing it yourself.
import { readFile } from 'fs/promises';
const json = JSON.parse(
await readFile(
new URL('./some-file.json', import.meta.url)
)
);
Option 2: Leverage the CommonJS require function to load JSON files
The documentation also states that you can use createRequire to load JSON files. This approach is the way Pawel advises in his blog post.
createRequire allows you to construct a CommonJS require function to use typical CommonJS features such as reading JSON in your Node.js EcmaScript modules.
import { createRequire } from "module";
const require = createRequire(import.meta.url);
const data = require("./data.json");
In TypeScript or using Babel, you can import json file in your code.
// Babel
import * as data from './example.json';
const word = data.name;
console.log(word); // output 'testing'
Reference:
https://hackernoon.com/import-json-into-typescript-8d465beded79
Importing JSON using ES modules was submitted as feature to TC39 in mid 2020, and is (at the time of this edit) in stage 3, which is the last stage before being accepted in to the spec (see https://github.com/tc39/proposal-json-modules for more details). Once landed, you will be able to use it as:
import someName from "./some/path/to/your/file.json";
Where someName is effectively the name of the variable for the JS object described by the JSON data. (And of course, note that this imports JavaScript from a JSON source, it does not "import JSON").
If you're using a modern enough bundler (like esbuild or the like) or you're using a recent enough transpiler (like babel) then you can already use this syntax without having to worry about support.
Alternatively, if you have the luxury of ownership of JSON files you can also turn your JSON into valid JS files with a minimum of extra code:
config.js
export default
{
// my json here...
}
then...
import config from '../config.js'
does not allow import of existing .json files, but does a job.
Unfortunately, ES6/ES2015 doesn't support loading JSON via the module import syntax. But...
There are many ways you can do it. Depending on your needs, you can either look into how to read files in JavaScript (window.FileReader could be an option if you're running in the browser) or use some other loaders as described in other questions (assuming you are using NodeJS).
IMO simplest way is probably to just put the JSON as a JS object into an ES6 module and export it. That way, you can just import it where you need it.
Also, worth noting if you're using Webpack, importing of JSON files will work by default (since webpack >= v2.0.0).
import config from '../config.json';
If you're using node you can:
const fs = require('fs');
const { config } = JSON.parse(fs.readFileSync('../config.json'));
OR
const evaluation = require('../config.json');
// evaluation will then contain all props, so evaluation.config
// or you could use:
const { config } = require('../config.json');
Else:
// config.js
{
// json object here
}
// script.js
import { config } from '../config.js';
OR
import * from '../config.json'
I'm using babel+browserify and I have a JSON file in a directory ./i18n/locale-en.json with translations namespace (to be used with ngTranslate).
Without having to export anything from the JSON file (which btw is not possible), I could make a default import of its content with this syntax:
import translationsJSON from './i18n/locale-en';
Depending on your build tooling and the data structure within the JSON file, it may require importing the default.
import { default as config } from '../config.json';
e.g. usage within Next.js
In a browser with fetch (basically all of them now):
At the moment, we can't import files with a JSON mime type, only files with a JavaScript mime type. It might be a feature added in the future (official discussion).
fetch('./file.json')
.then(response => response.json())
.then(obj => console.log(obj))
In Node.js v13.2+:
It currently requires the --experimental-json-modules flag, otherwise it isn't supported by default.
Try running
node --input-type module --experimental-json-modules --eval "import obj from './file.json'; console.log(obj)"
and see the obj content outputted to console.
Thanks to all the people who proposed and implemented JSON modules and Import Assertions. Since Chrome 91, you can import JSON directly, for example:
// test.json
{
"hello": "world"
}
// Static Import
import json from "./test.json" assert { type: "json" };
console.log(json.hello);
// Dynamic Import
const { default: json } = await import("./test.json", { assert: { type: "json" } });
console.log(json.hello);
// Dynamic Import
import("./test.json", { assert: { type: "json" } })
.then(module => console.log(module.default.hello));
Note: other browsers may not yet implement this feature at the moment.
A bit late, but I just stumbled across the same problem while trying to provide analytics for my web app that involved sending app version based on the package.json version.
Configuration is as follows: React + Redux, Webpack 3.5.6
The json-loader isn't doing much since Webpack 2+, so after some fiddling with it, I ended up removing it.
The solution that actually worked for me, was simply using fetch.
While this will most probably enforce some code changes to adapt to the async approach, it worked perfectly, especially given the fact that fetch will offer json decoding on the fly.
So here it is:
fetch('../../package.json')
.then(resp => resp.json())
.then((packageJson) => {
console.log(packageJson.version);
});
Do keep in mind, that since we're talking about package.json specifically here, the file will not usually come bundled in your production build (or even dev for that matter), so you will have to use the CopyWebpackPlugin to have access to it when using fetch.
Simply do this:
import * as importedConfig from '../config.json';
Then use it like the following:
const config = importedConfig.default;
Adding to the other answers, in Node.js it is possible to use require to read JSON files even inside ES modules. I found this to be especially useful when reading files inside other packages, because it takes advantage of Node's own module resolution strategy to locate the file.
require in an ES module must be first created with createRequire.
Here is a complete example:
import { createRequire } from 'module';
const require = createRequire(import.meta.url);
const packageJson = require('typescript/package.json');
console.log(`You have TypeScript version ${packageJson.version} installed.`);
In a project with TypeScript installed, the code above will read and print the TypeScript version number from package.json.
For NodeJS v12 and above, --experimental-json-modules would do the trick, without any help from babel.
https://nodejs.org/docs/latest-v14.x/api/esm.html#esm_experimental_json_modules
But it is imported in commonjs form, so import { a, b } from 'c.json' is not yet supported.
But you can do:
import c from 'c.json';
const { a, b } = c;
import data from "./resource.json”
is possible in Chrome 91.
JSON modules are now supported. This allows developers to statically import JSON instead of relying on the fetch() function which dynamically retrieves it.
https://www.stefanjudis.com/snippets/how-to-import-json-files-in-es-modules/
A more elegant solution is to use the CommonJS require function
createRequire construct a CommonJS require function so that you can use typical CommonJS features such as reading JSON
import { createRequire } from "module";
const require = createRequire(import.meta.url);
const data = require("./data.json");
importing JSON files are still experimental. It can be supported via the below flag.
--experimental-json-modules
otherwise you can load your JSON file relative to import.meta.url with fs directly:-
import { readFile } from 'fs/promises';
const config = JSON.parse(await readFile(new URL('../config.json', import.meta.url)));
you can also use module.createRequire()
import { createRequire } from 'module';
const require = createRequire(import.meta.url);
const config = require('../config.json');
I used it installing the plugin "babel-plugin-inline-json-import" and then in .balberc add the plugin.
Install plugin
npm install --save-dev babel-plugin-inline-json-import
Config plugin in babelrc
"plugin": [
"inline-json-import"
]
And this is the code where I use it
import es from './es.json'
import en from './en.json'
export const dictionary = { es, en }
I'm using
vuejs, version: 2.6.12
vuex, version: 3.6.0
vuex-i18n, version: 1.13.1.
My solution is:
messages.js:
import Vue from 'vue'
import Vuex from 'vuex';
import vuexI18n from 'vuex-i18n';
import translationsPl from './messages_pl'
import translationsEn from './messages_en'
Vue.use(Vuex);
export const messages = new Vuex.Store();
Vue.use(vuexI18n.plugin, messages);
Vue.i18n.add('en', translationsEn);
Vue.i18n.add('pl', translationsPl);
Vue.i18n.set('pl');
messages_pl.json:
{
"loadingSpinner.text:"Ładowanie..."
}
messages_en.json:
{
"loadingSpinner.default.text":"Loading..."
}
majn.js
import {messages} from './i18n/messages'
Vue.use(messages);
let filePath = '../../data/my-file.json'
let arrayImport = await import(filePath, {
assert: { type: "json" },
});
const inputArray = arrayImport.default
console.log('result', inputArray)
More information here: v8 - Dynamic import().
As said by Azad, the correct answer is to load the file with fs.readFileSync() (or any of the asynchronous variants such as fs.readFile with callback or fs.promises.readFile with promises/await, then parse the JSON with JSON.parse()
const packageJsonRaw = fs.readFileSync('location/to/package.json' )
const packageJson = JSON.parse(packageJsonRaw )
Webpack/Babel options are not practical unless you are already using that set up.
Make sure the type attribute is set to module because we are using the ES6 Modules syntax.
And here is how we would import a JSON file in our index.js file.
import myJson from './example.json' assert {type: 'json'};
import a JSON file in ECMAScript 6
import myJson from './example.json' assert {type: 'json'};
https://www.stefanjudis.com/snippets/how-to-import-json-files-in-es-modules-node-js/
ES modules are still reasonably new in Node.js land (they're stable since Node 14). Modules come with a built-in module system, and features such as top-level await.
I read an informative post on ES modules by Pawel Grzybek and learned that you can't import JSON files in ES modules today.
import info from `./package.json` assert { type: `json` };
const { default: info } = await import("./package.json", {
assert: {
type: "json",
},
});
That's a real bummer because I'm pretty used to doing require calls such as const data = require('./some-file.json') in Node.js.
But can you use import assertions in Node.js today?
At the time of writing, the current Node.js LTS (v18.12) still marks import assertions as experimental.
This post explains ways to deal with JSON in ES modules if you don't want to use the experimental feature yet.
Option 1: Read and parse JSON files yourself
The Node.js documentation advises to use the fs module and do the work of reading the files and parsing it yourself.
import { readFile } from 'fs/promises';
const json = JSON.parse(
await readFile(
new URL('./some-file.json', import.meta.url)
)
);
Option 2: Leverage the CommonJS require function to load JSON files
The documentation also states that you can use createRequire to load JSON files. This approach is the way Pawel advises in his blog post.
createRequire allows you to construct a CommonJS require function to use typical CommonJS features such as reading JSON in your Node.js EcmaScript modules.
import { createRequire } from "module";
const require = createRequire(import.meta.url);
const data = require("./data.json");
The file structure with the json extension is used to transfer data, the json file data can be retrieved locally by sending a request using the fetch command.
In the following example, the data of the count.json file is received
// count.json
fetch("./count.json")
.then((response) => { return response.json(); })
.then((data) => console.log(data));