import functions from 'firebase-functions';
import UtilModuler from '#utilModuler'
exports.helloWorld = functions.https.onRequest((request, response) => {
response.send("Hello from Firebase!");
});
import UtilModuler from '#utilModuler';
^^^^^^^^^
SyntaxError: Unexpected identifier
at Module._compile (internal/modules/cjs/loader.js:721:23)
Caveats
I'm using third party libraries(#utilModuler) which were written via import/exports. Possible workarounds:
Fork library and generate cjs file with rollup.
esm works like a charm but it cause unnesecary memory consumptions
Question: is there are a way how to use hybrid import cjs and esm in google cloud function?(except options which I described above)
Would be nice to use in deploy function something like --experimental-modules
It looks like, ESM support has been added by the latest version of the firebase CLI (https://github.com/firebase/firebase-tools/releases/tag/v9.15.0):
$ npm install -g firebase-tools # Get the latest firebase-cli
$ firebase deploy --only functions # Deploy as usual
and
You must select nodejs14 runtime.
You must manually include latest version of #google-cloud/functions-framework dependency.
e.g.
// package.json
...
"engines": {
"node": "14"
},
"type": "module",
"dependencies": {
"#google-cloud/functions-framework": "^1.9.0",
...
},
and an example function:
// index.js
import functions from "firebase-functions";
export const helloWorld = functions.https.onRequest((request, response) => {
response.send("Hello from Firebase!");
});
"devDependencies": {
"#babel/core": "^7.2.0",
"#babel/preset-env": "^7.2.0",
"#babel/register": "^7.0.0"
}
.babelrc
{
"presets": ["#babel/preset-env"]
}
entry point node.js app
require("#babel/register")({})
// Import the rest of our application.
module.exports = require('./index.js')
Related
I am currently developing my own npm package and I created a separate project to download this package from npm for an independent test. The package is being developed in typescript and I have a main file with several additional module files. In my main file, I am importing all of the classes from the other modules, then exporting all of them under the main file. I don't know if this is good practice but when I run the main file on the test project, it says it can't find the module when the path it specifies exists in the working directory.
Code Snippets:
Main file:
import { EventBus } from "./modules/eventbus/eventbus";
import { EventHandler } from "./modules/eventbus/eventhandler";
import { EventType } from "./modules/eventbus/eventtype";
import { Event } from "./modules/eventbus/event";
import { SemVer } from "./modules/semver";
export { SemVer, Event, EventBus, EventHandler, EventType };
Error:
Error [ERR_MODULE_NOT_FOUND]: Cannot find module '/workspaces/epic-engine-testing/node_modules/epic-engine/lib/modules/eventbus/eventbus' imported from /workspaces/epic-engine-testing/node_modules/epic-engine/lib/index.js
Working directory:
Testing file:
import { EventBus, EventHandler, EventType, Event } from "epic-engine";
class SomeType extends EventType {
constructor() {
super();
}
}
const eventbus = new EventBus();
const handler = new EventHandler<SomeType>(eventbus, "type", () => {});
eventbus.createHandler(handler);
const event = new Event<SomeType>(eventbus, new SomeType(), "type");
package.json:
{
"devDependencies": {
"#tsconfig/esm": "^1.0.2",
"#types/jest": "^29.2.3",
"jest": "^29.3.1",
"ts-jest": "^29.0.3",
"tslint": "^6.1.3",
"typescript": "^4.9.3"
},
"name": "epic-engine",
"description": "Pure TS engine developed by EpicPuppy613",
"version": "0.1.0-dev.5",
"main": "lib/index.js",
"types": "lib/index.d.ts",
"type": "module",
"scripts": {
"test": "jest --config jestconfig.json",
"build": "tsc",
"prepare": "npm run build",
"lint": "tslint -p tsconfig.json",
"prepublishOnly": "npm test && npm run lint",
"preversion": "npm run lint",
"version": "git add -A src",
"postversion": "git push && git push --tags"
},
"repository": {
"type": "git",
"url": "git+https://github.com/EpicPuppy613/epic-engine.git"
},
"author": "EpicPuppy613",
"license": "MIT",
"bugs": {
"url": "https://github.com/EpicPuppy613/epic-engine/issues"
},
"homepage": "https://github.com/EpicPuppy613/epic-engine#readme",
"files": [
"lib/**/*"
]
}
I tried a bunch of things including changing the references to use .js, using absolute paths instead, and changing some settings in tsconfig.json.
Why is Node.js not finding the submodules or would it be better to export the modules in a different way?
Save time with npm link command
I created a separate project to download this package from npm for an independent test.
First, you can use the handy npm link command to save yourself the trouble of uploading your package just so you can test. As per the docs the npm link command:
...is handy for installing your own stuff, so that you can work on it and test iteratively without having to continually rebuild.
Install your package as a dependency
With that out of the way, I think the hint is in the error message. Note it says:
Cannot find module /workspaces/epic-engine-testing/node_modules/...
Here it seems Node is looking for the file in the epic-engine-testing project, so you must have the package.json file for the test project reference your package (i.e. the one you want to test). So go into your epic-engine-testing project folder and at the terminal type npm install epic-engine#0.1.0-dev.5. That should install your package so it can be found. If that doesn't resolve it, you'll need to share the package.json file for the epic-engine-testing to help us see what's going on.
Using the export { ... } from '...' syntax
Your main file can use the re-exports synax and be simplified to this when exporting:
export { EventBus } from "./modules/eventbus/eventbus";
export { EventHandler } from "./modules/eventbus/eventhandler";
export { EventType } from "./modules/eventbus/eventtype";
export { Event } from "./modules/eventbus/event";
export { SemVer } from "./modules/semver";
// the line below is not necessary when using above syntax.
// export { SemVer, Event, EventBus, EventHandler, EventType };
After compiling the ts files into js files, wherever you have import syntax, Node.js looks for .js files to resolve them. So it needs to be explicitly given a module name with .js extension in import.
You may need to read this doc on how the import mechanism works in Node.js.
To fix this issue, you have multiple choices(since the target you've defined is ES6):
change moduleResolution to nodeNext and add .js extension whenever you would importing modules in typescript:
import { EventBus } from "./modules/eventbus/eventbus.js";
import { EventHandler } from "./modules/eventbus/eventhandler.js";
import { EventType } from "./modules/eventbus/eventtype.js";
...
You don't need to be worried about it, typescript is well smart. Based on this comment from one of typescript contributor:
.js file extensions are now allowed
Using rollup package. The rollup package won't manipulate your files. Instead, it bundles your output files.
Maintainer of multiple npm packages here. Been using mocha with the require syntax and wanting to migrate to the import syntax.
The error I am getting is
Cannot find module '<project>/src/index' imported from <project>/test/index.spec.js
Steps to Reproduce
With the following three files
src/index.js
export const sum = (a, b) => a + b;
test/index.spec.js
import { sum } from '../src/index';
const expect = require('chai').expect;
describe('Testing Index', () => {
it('Testing sum', () => {
expect(sum(7, 13)).to.equal(20);
});
});
package.json
{
"name": "mocha-debug",
"type": "module",
"main": "index.js",
"scripts": {
"test": "mocha \"./test/**/*.spec.js\""
},
"license": "ISC",
"devDependencies": {
"chai": "4.3.4",
"mocha": "9.1.4"
}
}
and using node v14.18.2, run yarn install and
yarn test
> `Cannot find module '<project>/src/index' imported from <project>/test/index.spec.js`
Notes
I've found a related issue that recommends using babel with --require #babel/register, but wasn't able to get over the error.
I've set up a test repo to make it easy to reproduce the issue
https://github.com/simlu/mocha-debug
Question
What am I doing wrong here? How do I get the tests to run successfully?
I solved it by just adding the file extension in my case I was importing my mongodb model so I imported with the file extension .ts
var Employee = require('../models/Employee.ts')
Which solved the issue
I've been looking around and can't seem to find a clear answer on this.
Is it possible to import an index.js file from a client directory using the directory name (omitting /index.js)? If so, how? This is a new project and I don't really want to bundle my code at this point.
The node version is v17.1.0.
File structure
package.json
server.js
src/
index.js
utils/
index.js
package.json
{
"type": "module",
"main": "server.js",
"scripts": {
"start": "nodemon --ignore src"
},
"devDependencies": {
"express": "^4.17.1",
"nodemon": "^2.0.14"
}
}
server.js
import express from 'express'
express()
.use(express.static('src'))
.get('/', (_, res) => res.send(`
<script type="module" src="index.js"></script>`))
.listen(3000, () => console.log(`Running at http://localhost:3000`))
src/index.js
import { stuff } from './utils'
// Firefox: Loading module from “http://localhost:3000/utils/”
// was blocked because of a disallowed MIME type (“text/html”).
I've tried running the app with node --experimental-specifier-resolution=node server.js and tried adding express.static.mime.define({'text/javascript': ['js']}) to server.js, but neither worked for me.
When I use "await" on top-level like this:
const LuckyDrawInstance=await new web3.eth.Contract(abi)
I got a warning on the terminal: "set experiments.topLevelAwait true". When I tried to add this to "tsconfig.json", it still does not work. it says "experiments" property does not exist.
I could wrap it inside an async function but I want to set it without a wrapped function.
It is nothing to do with the tsconfig.json. You have to set it inside next.config.js. New version of next.js uses webpack5 and webpack5 supports top level await.
module.exports = {
webpack: (config) => {
// this will override the experiments
config.experiments = { ...config.experiments, topLevelAwait: true };
// this will just update topLevelAwait property of config.experiments
// config.experiments.topLevelAwait = true
return config;
},
};
NOTE
You have to use it outside the functional component:
export default function Navbar() {
// this will throw error
// Syntax error: Unexpected reserved word 'await'.
const provider=await customFunction()
return (
<section>
</section>
);
}
Warning
Since it is experimental, it might be broken in some versions
The latest solution as of writing this post that worked for me is using Babel instead of SWC since Next.js does not allow custom SWC configuration, therefore, you cannot allow topLevelAwait through .swcrc file.
Add Babel plugin called #babel/plugin-syntax-top-level-await into your package.json.
eg.
{
"devDependencies": {
"#babel/plugin-syntax-top-level-await": "^7.14.5"
}
}
Create .babelrc file in the root directory of your project where package.json lives.
Inside .babelrc make sure to include next/babel preset and the topLevelAwait plugin.
eg.
{
"presets": ["next/babel"],
"plugins": [
"#babel/plugin-syntax-top-level-await"
]
}
This is the easiest solution until Next.js team allows us to include SWC configuration. Note that by doing this you will not have SWC performance benefit since it will be disabled in favor of Babel.
I have been struggling with this for 2-3 days. Here is a solution that works. Please follow the following steps.
1. Copy paste the following in your package.json
{
"name": "projectname",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "mocha",
"dev": "next dev"
},
"author": "",
"license": "ISC",
"dependencies": {
"#truffle/hdwallet-provider": "^2.0.1",
"fs-extra": "^10.0.0",
"ganache-cli": "^6.12.2",
"mocha": "^9.1.4",
"next": "^12.0.8",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"solc": "^0.8.9",
"web3": "^1.7.0",
"#babel/plugin-syntax-top-level-await": "^7.14.5"
},
"devDependencies": {
"#babel/plugin-syntax-top-level-await": "^7.14.5"
}
}
2. Delete your node_modules folder
3. Goto your project's root directory and reinstall all the packages using npm install command
4. Create a new file in your project's root directory and call it "next.config.js"
5. Copy paste following code in next.config.js file and save.
module.exports = {
// target: 'experimental-serverless-trace',
webpack: (config) => {
config.experiments = config.experiments || {};
config.experiments.topLevelAwait = true;
return config;
},
};
I'm new to Node.js, please help me.
What is wrong?
Using typescript, SQLite3 and Knex, with migration.
I get the error when running "yarn knex: migrate" or "knex migrate: latest":
$ knex migrate:latest
Requiring external module ts-node/register
Error: knex: Required configuration option 'client' is missing
These are my files:
package.json:
{
"name": "backend",
"version": "1.0.0",
"main": "index.js",
"license": "MIT",
"scripts": {
"start": "ts-node-dev --transpile-only --ignore-watch node-modules --respawn
src/server.ts",
"knex:migrate": "knex --knexfile knexfile.ts migrate:latest",
"knex:migrate:rollback": "knex --knexfile knexfile.ts migrate:rollback"
},
"devDependencies": {
"#types/express": "^4.17.11",
"ts-node": "^9.1.1",
"ts-node-dev": "^1.1.6",
"typescript": "^4.2.4"
},
"dependencies": {
"espress": "^0.0.0",
"express": "^4.17.1",
"knex": "^0.95.4",
"sqlite3": "^5.0.2"
}
}
knexfile.ts:
import path from'path';
module.exports = {
cliente: 'sqlite3',
connection: {
filename: path.resolve(__dirname, 'src', 'database', 'resp.sqlite')
},
migrations: {
directory: path.resolve(__dirname, 'src', 'database', 'migrations'),
},
useNullAsDefault: true,
};
Migration 00_create_organizacoes.ts:
import knex from 'knex';
export async function up(knex: knex) {
return knex.schema.createTable('organizacoes', table => {
table.increments('id').primary();
table.string('razaosocial_org').notNullable();
table.integer('atividade_org').notNullable();
table.timestamp('criacao_org').defaultTo(knex.fn.now());
table.timestamp('atualizacao_org').defaultTo(knex.fn.now());
});
}
export async function down(knex: knex) {
return knex.schema.droptable('organizacoes');
};
My file structure:
enter image description here
Unsuccessful in other treatments.
Looks like you have a typo in your knexfile.ts
The name of the missing property is client and not cliente
The Requiring external module ts-node/register message you get is not the issue, the issue is that in the knexfile.ts the client property is not read. From the example above change the cliente property to client and it is fixed.
What if you have no spelling error, client exist in your configuration, and you are getting this message? Are you using a env file? If yes, In your knexfile.ts print the value from your env file. If it returns undefined, it means that no value was read for the env file. Check if you have the dotenv package installed and configured properly. Also check that your env file has a key called client and the value is available and in the knexfile.ts ensure you are calling the right key from your env.
Finally if the problem is not solved and every other thing is in-place, require dotenv in your package.json file before running a command as shown below.
"migrate:latest": "ts-node -r dotenv/config ./node_modules/knex/bin/cli.js migrate:latest
The ts-node -r dotenv/config ensures that the details in the env file are added to the environment.
The ./node_modules/knex/bin/cli.js starts the knex cli so that the remaining part which is a knex command can be executed.