now-cli deployment doesn't build package.json dependencies - node.js

I'm trying to deploy a Sapper built application via
#now-node. The task is basically to deploy a Polka server with dependencies and to serve static/ and client/ files statically. I have managed to include the files that Lambda requires via includeFiles but now I see in the logs that the builder ignores dependencies described in package.json. The exact message is
Starting server on port 3000
Cannot find module 'sirv'
Did you forget to add it to "dependencies" in `package.json`?
But I see in the build log that dependencies are not collected. Both package.json and package-lock.json are present in the source files.
I'd appreciate any advice on how to approach this.
The now.json config I arrived at looks like this:
{
"version": 2,
"name": "experimental-sapper",
"builds": [
{
"src": "__sapper__/build/index.js",
"use": "#now/node",
"config": {
"includeFiles": [
"../build/**",
"../../static/**"
]
}
},
{
"src": "static/**",
"use": "#now/static"
},
{
"src": "__sapper__/build/client/**",
"use": "#now/static"
}
],
"routes": [
{ "src": "/(.*(\\.css)|(\\.json)|(\\.png))", "dest": "/static/$1" },
{ "src": "/client/(.*)", "dest": "/__sapper__/build/client/$1" },
{ "src": "/(.*)", "dest": "/__sapper__/build/index.js" }
],
"alias": "..."
}
And the src/server.js looks like this (before Rollup bundling):
import sirv from 'sirv';
import polka from 'polka';
import compression from 'compression';
import * as sapper from '#sapper/server';
const { PORT, NODE_ENV } = process.env;
const dev = NODE_ENV === 'development';
const app = polka() // You can also use Express
.use(compression({ threshold: 0 }));
if (dev) {
app.use(sirv('static', { dev }));
}
app.use(sapper.middleware())
.listen(PORT, err => {
if (err) console.log('error', err);
});
export default app.handler;
Then package.json is pretty standard as well:
"description": "TODO",
"version": "0.0.1",
"scripts": {
"dev": "sapper dev",
"build": "sapper build --legacy",
"export": "sapper export --legacy",
"start": "node __sapper__/build",
"cy:run": "cypress run",
"cy:open": "cypress open",
"test": "run-p --race dev cy:run"
},
"dependencies": {
"compression": "^1.7.1",
"express": "^4.17.1",
"polka": "^0.5.0",
"postcss-define-property": "^0.5.0",
"sirv": "^0.4.0"
},
"devDependencies": {
...
},
"browserslist": "last 2 versions"
}
Thanks in advance!

For anybody coming across this question, the solution is to use the now-sapper builder at https://www.npmjs.com/package/now-sapper
There are instructions on the site, but essentially you need to export your handler as mentioned above, then let the builder do the rest. There are a few intricacies to now which mean that the node builder alone won't work.
Your now configuration should look like:
{
"version": 2,
"builds": [
{
"src": "package.json",
"use": "now-sapper"
}
]
}
There is a demo project linked from the README which is a basic Sapper template with the required now configuration.
Note for exported applications, #now/static will suffice.

Related

How to properly combine aframe, threeJS, npm, and webpack?

I am trying to understand the expected way to set up an AFRAME project and use npm/webpack to install dependencies, including things like three/addons.
I am new to node (and especially webpack), but I have a package.json set up to run a simple server:
{
"name": "test",
"version": "0.0.1",
"description": "test",
"main": "server.js",
"scripts": {
"start": "node server.js",
},
"dependencies": {
"aframe": "^1.3.0"
}
"engines": {
"node": ">=16"
}
}
In my /public directory, I have several html files + js files in various nested directories which use AFRAME (which I was previously loading from CDN).
What's the "right" way to give these scripts access to AFRAME without CDN? What about three, three/addons, or any other ThreeJS/AFRAME npm package?
I gather that I need to use webpack? Can I configure webpack to generate a single bundle.js file that includes all of my dependencies, and then import as desired from that? I don't fully understand the relationship between webpack's bundling and ES6 imports, or how to configure webpack in this way.
Thank you!
EDIT: based on the comments below, here is my package.json now:
{
"name": "test",
"version": "0.0.1",
"description": "test",
"main": "server.js",
"scripts": {
"start": "node server.js"
},
"dependencies": {
"aframe": "git://github.com/aframevr/aframe.git#54022b80c60b12dc755f4f4a71a779b410dd23d0",
"aframe-htmlembed-component": "^1.0.0",
"aframe-extras": "^6.1.1",
"aframe-instanced-mesh": "^0.6.1",
"networked-aframe": "^0.11.0",
"#react-three/drei": "^9.46.3"
},
"devDependencies": {
"webpack": "^5.75.0",
"webpack-cli": "^5.0.0"
},
"engines": {
"node": ">=16"
}
}
webpack.config.js:
// From: https://github.com/Chabloz/a-frame-webpack-boilerplate
const path = require("path");
const config = {
mode: "development",
devtool: "inline-source-map",
entry: "./src/main.js",
output: {
filename: "bundle.js",
path: path.resolve(__dirname, "public/dist")
},
watch: false,
resolve: {
modules: [
path.resolve("./src"),
path.resolve("./node_modules")
]
},
externals: {
three: "THREE"
}
};
module.exports = (env, argv) => {
return config;
};
and /src/main.js:
// AFRAME
require("aframe");
// Helpers
require("aframe-htmlembed-component");
require("aframe-extras");
require("aframe-instanced-mesh/src/instanced-mesh");
require("#react-three/drei");
// NAF
require("networked-aframe");
This sucessfully generates /public/dist/bundle.js when I run webpack, and I can include it like so:
<script src="/dist/bundle.js"></script>
But when I try to import any of the modules in the bundle from another script (import * as THREE from "three"), I get Uncaught TypeError: Failed to resolve module specifier "three". Relative references must start with either "/", "./", or "../".. If I change it to import * as THREE from "/dist/bundle.js", I get bundle.js:36779 Uncaught Error: A a-node type is already registered

Jest: node.js SyntaxError: Cannot use import statement outside a module

I have just started learning jest testing and created a sample application to get familiar with jest testing. However, I am getting following error...
Language.js
const calculateTip = (total, percentage) => {
return total + ((percentage / 100) * total) + 1;
};
export {
calculateTip,
}
package.json
{
"dependencies": {
"express": "^4.18.2"
},
"type": "module",
"main": "src/app.js",
"scripts": {
"start": "node src/app.js",
"test": "cls && env-cmd -f ./envs/test.env jest --watchAll"
},
"devDependencies": {
"env-cmd": "^10.1.0",
"jest": "^29.2.2",
"supertest": "^6.3.1"
}
}
I have tried googling for the solution but no luck so far.
Node.js supports esm syntax only from v16, but jest doesn't support it yet.
Therefore, you have 2 choices:
Don't use the esm syntax (import / export)
Add jest-babel with it's config to transpile (convert) esm syntax to cjs one.
You can fix it by installing jest-babel and then creating babel.config.cjs in your root directory and pasting the following into it:
//babel.config.cjs
module.exports = {
presets: [
[
'#babel/preset-env',
{
targets: {
node: 'current',
},
},
],
],
};
...
//package.json
"type": "module"
//tsconfig.json
...
"target": "esnext",
"module": "commonjs",
...

Packaging Electron + Puppeteer to a .exe

Hi I have an Electron app that's running Puppeteer (To be specific it is puppeteer-cluster). I want to be able to package this app into a .exe that I can distribute with.
One requirement though is that I have to be able to pack it with --asar.
Here's some stuff I tried but failed:
I tried setting the executable path :
let ChromiumPath = path.join(__dirname, "..", "..", "..",".local-chromium", "win64-809590", "chrome-win","chrome.exe");
const cluster = await Cluster.launch({
puppeteer,
concurrency: Cluster.CONCURRENCY_BROWSER,
maxConcurrency: arg.length,
timeout: 340000,
puppeteerOptions: {
args: browserArgs,
headless: false,
ignoreHTTPSErrors: true,
executablePath : ChromiumPath
},
perBrowserOptions: perBrowserOptions,
});
I tried specifying the unpack directory in package.json
"config": {
"forge": {
"packagerConfig": {
"asar": {
"unpack": "**/node_modules/puppeteer/.local-chromium/**/*"
}
}.....
Here's how i package my app:
electron-packager . --asar
And if needed, here's my package.json:
{
"name": "testBrowsers",
"productName": "testBrowsers",
"version": "1.0.0",
"description": "IDk",
"main": "src/index.js",
"scripts": {
"start": "electron-forge start",
"package": "electron-packager ./ testBrowsers --platform=win32 --arch=x64 --icon=./tool.ico --out=./dist --electron-version=10.1.4 --overwrite",
"make": "electron-forge make",
"publish": "electron-forge publish",
"lint": "echo \"No linting configured\""
},
"keywords": [],
"author": "Otter",
"license": "MIT",
"config": {
"forge": {
"packagerConfig": {
"asar": {
"unpack": "**/node_modules/puppeteer/.local-chromium/**/*"
}
},
"makers": [
{
"name": "#electron-forge/maker-squirrel",
"config": {
"name": "testBrowsers"
}
},
{
"name": "#electron-forge/maker-zip",
"platforms": [
"darwin"
]
},
{
"name": "#electron-forge/maker-deb",
"config": {}
},
{
"name": "#electron-forge/maker-rpm",
"config": {}
}
]
}
},
"dependencies": {
"electron-squirrel-startup": "^1.0.0",
"proxy-chain": "^0.4.5",
"puppeteer": "^5.4.1",
"puppeteer-cluster": "^0.22.0",
"puppeteer-extra": "^3.1.15",
"puppeteer-extra-plugin-stealth": "^2.6.5",
"puppeteer-page-proxy": "^1.2.8",
"taskkill": "^3.1.0"
},
"devDependencies": {
"#electron-forge/cli": "^6.0.0-beta.54",
"#electron-forge/maker-deb": "^6.0.0-beta.54",
"#electron-forge/maker-rpm": "^6.0.0-beta.54",
"#electron-forge/maker-squirrel": "^6.0.0-beta.54",
"#electron-forge/maker-zip": "^6.0.0-beta.54",
"electron": "10.1.4"
}
}
Thanks I really hope someone can help me out with this issue! :)
You will probably need to package chromium separately from your application. At least that's what you would do when trying to package a node application using something like pkg.
You can load chromium in puppeteer from a custom install path when launching a browser instance. So in code you will need to specify that path and make sure that your packaged app has the ability to read that path.
Your distribution file (probably an archive) will then have the chromium build that puppeteer needs separate from the actual app exe
have a look at a similar discussion here
https://github.com/vercel/pkg/issues/204

Is there a way to stop Intellisense from importing all Mocha (or other test library) globals into non-test files?

I have these files in the same directory.
package.json:
{
"name": "example",
"version": "1.0.0",
"devDependencies": {
"#types/mocha": "^7.0.1",
"#types/node": "^13.7.1"
}
}
tsconfig.json:
{}
index.ts:
export const test = () => 'test'
index.spec.ts:
import assert from 'assert'
import {test} from '.'
describe('test function', () => {
it('should return test', () => assert.strictEqual(test(), 'test'))
})
Even without using import 'mocha' in index.spec.ts, Intellisense (in VSCode) seems to import the Mocha globals and therefore allows describe and it. describe and it are also allowed in index.ts.
Is there a way to stop this and allow me to specify that Mocha should only be imported in index.spec.ts?
I found a way to do it, but it isn't that nice:
tsconfig.json
{
"include": ["**/*.ts"],
"compilerOptions": {
// put compiler options here
}
}
tsconfig.src.json
{
"extends": "./tsconfig.json",
"include": ["**/*.ts"], // or wherever your source files are (e.g. src/**/*.ts)
"exclude": ["**/*.spec.ts"],
"compilerOptions": {
// List all the types that the src folder needs
// (should be everything except for mocha/jest/etc.)
"types": ["node"]
}
}
tsconfig.test.json
{
"extends": "./tsconfig.json",
"include": ["**/*.spec.ts"] // or wherever your tests are
// Since asking this question I now put my tests in tests/**/*.ts
}
While VSCode will use tsconfig.json for all files, your build script can pick up if you've used for example describe or test in your source files:
package.json
{
"name": "example",
"version": "1.0.0",
"scripts": {
"build": "tsc -p tsconfig.src.json && tsc -p tsconfig.test.json"
},
"devDependencies": {
"#types/mocha": "^7.0.1",
"#types/node": "^13.7.1"
}
}

DEPS_RESOLVE_FAILED on module when building a web application with Brunch in ES6

I'm having an issue when building my web application using Brunch. My application depends on a module I've created and uploaded to NPM, and whenever I build it, I get:
DEPS_RESOLVE_FAILED of node_modules/rd-vue-bootstrap/dist/rd-vue-bootstrap.js failed.
Could not load module './bs-button-group.vue' from '/Users/rjuliani/dev/production-manager-ui/node_modules/rd-vue-bootstrap/dist'.
Make sure the file actually exists
The module itself builds just fine, however when I use it from my test web application and build it (the web application) it throw me the above error.
The relevant parts of my package.json file for the module are:
"main": "dist/rd-vue-bootstrap.js",
"files": [
"dist/rd-vue-bootstrap.js",
"dist/rd-vue-bootstrap.js.map",
"dist/rd-vue-bootstrap.min.js",
"src"
],
brunch-config.js
module.exports = {
files: {
javascripts: {
joinTo: 'app.js'
},
templates: {
joinTo: 'app.js'
}
},
plugins: {
babel: {
},
assetsmanager: {
copyTo: {
'vendor': ['node_modules/bootstrap', 'node_modules/jquery', 'node_modules/rd-vue-bootstrap']
},
minTimeSpanSeconds: 10 // assets won't be copied more frequent than once per X seconds.npm
}
}
};
initialize.js (main file for my web application)
import Vue from 'vue';
import RdVueBootstrap from 'rd-vue-bootstrap';
Vue.use(RdVueBootstrap);
Finally, package.json for my test web application
{
"name": "production-manager-ui",
"description": "Simple UI for the production-manager API project",
"version": "0.0.1",
"license": "MIT",
"repository": {
"type": "git",
"url": "https://github.com/radical-dreamers/production-manager-ui.git"
},
"scripts": {
"watch": "brunch watch --server",
"build": "brunch build --production"
},
"author": {
"url": "http://www.codelightsoftware.com",
"name": "Rodrigo Juliani",
"email": "srodriki#gmail.com"
},
"keywords": [
"vue",
"brunch"
],
"dependencies": {
"bootstrap": "^3.3.7",
"jquery": "^3.1.0",
"rd-vue-bootstrap": "0.0.6",
"vue": "^1.0.26",
"vue-router": "^0.7.13"
},
"devDependencies": {
"assetsmanager-brunch": "^1.8.1",
"auto-reload-brunch": "^2.7.1",
"babel-brunch": "^6.0.6",
"brunch": "^2.8.2",
"css-brunch": "^2.6.1",
"javascript-brunch": "^2.0.0",
"vue-brunch": "^1.1.2",
"vue-devtools": "^2.0.4"
}
}
Any ideas how to fix this? I've tried many things and nothing seems to be working as of right now :(
Thanks!

Resources