Executing node module script in packaged electron app - node.js

I was trying to execute node_modules/some_package/some_js.js from renderer using contextBridge. It works in dev server, but in packaged app.
Here is my preload.js code.
import { exec, fork } from "child_process";
import { contextBridge } from "electron";
import path from "path";
contextBridge.exposeInMainWorld("pwr", {
node: () => {
const __dirname = path.resolve();
const child_argv = ["codegen", ""];
const child_execArgv = ["codegen"];
fork(__dirname + "/node_modules/playwright-core/cli.js", child_argv);
},
here is my client-side(renderer) code...
const handleClick = () => {
//#ts-ignore
pwr.node();
};
here is package.json
"scripts": {
"dev": "vite",
"build": "tsc && vite build && electron-builder"
},
and this is vite config file
rmSync(path.join(__dirname, 'dist'), { recursive: true, force: true }) // v14.14.0
// https://vitejs.dev/config/
export default defineConfig({
resolve: {
alias: {
'#': path.join(__dirname, 'src'),
'styles': path.join(__dirname, 'src/assets/styles'),
},
},
plugins: [
react(),
electron({
main: {
entry: 'electron/main/index.ts',
vite: {
build: {
// For Debug
sourcemap: true,
outDir: 'dist/electron/main',
},
// Will start Electron via VSCode Debug
plugins: [process.env.VSCODE_DEBUG ? onstart() : null],
},
},
preload: {
input: {
// You can configure multiple preload scripts here
index: path.join(__dirname, 'electron/preload/index.ts'),
},
vite: {
build: {
// For Debug
sourcemap: 'inline',
outDir: 'dist/electron/preload',
}
},
},
// Enables use of Node.js API in the Electron-Renderer
// https://github.com/electron-vite/vite-plugin-electron/tree/main/packages/electron-renderer#electron-renderervite-serve
renderer: {},
}),
],
server: process.env.VSCODE_DEBUG ? {
host: pkg.debug.env.VITE_DEV_SERVER_HOSTNAME,
port: pkg.debug.env.VITE_DEV_SERVER_PORT,
} : undefined,
})
Source Code:
https://github.com/liansnail/electron-demo
Build Tool: Vite
OS: mac arm64
node version: 16.14.2
Please let me know what I'm missing. I used Vite for
Edit: I turned off asar option but it still doesn't work.
"scripts": {
"dev": "vite",
"build": "tsc && vite build && electron-builder build --config.asar=false"
},

Related

How to use imports in content script with Vite without external library like https://crxjs.dev/vite-plugin?

There's an issue with importing es modules into the content script:
(How to import ES6 modules in content script for Chrome Extension)
Maybe there is a way to build the content script in one file to resolve this?
I'm using this boilerplate - https://github.com/JohnBra/vite-web-extension. Here's what my vite config looks like:
import react from "#vitejs/plugin-react-swc";
import { resolve } from "path";
import { defineConfig } from "vite";
import copyContentStyle from "./utils/plugins/copy-content-style";
import makeManifest from "./utils/plugins/make-manifest";
const root = resolve(__dirname, "src");
const pagesDir = resolve(root, "pages");
const assetsDir = resolve(root, "assets");
const outDir = resolve(__dirname, "dist");
const publicDir = resolve(__dirname, "public");
const IS_DEV = process.env.DEV === "true";
export default defineConfig({
resolve: {
alias: {
"#src": root,
"#assets": assetsDir,
"#pages": pagesDir,
},
},
plugins: [react(), makeManifest(), copyContentStyle()],
publicDir,
build: {
minify: !IS_DEV,
outDir,
sourcemap: IS_DEV,
emptyOutDir: IS_DEV,
rollupOptions: {
input: {
// devtools: resolve(pagesDir, 'devtools', 'index.html'),
// panel: resolve(pagesDir, "panel", "index.html"),
content: resolve(pagesDir, "content", "index.ts"),
background: resolve(pagesDir, "background", "index.ts"),
popup: resolve(pagesDir, "popup", "index.html"),
// newtab: resolve(pagesDir, "newtab", "index.html"),
// options: resolve(pagesDir, "options", "index.html"),
},
output: {
entryFileNames: (chunk) => {
return `src/pages/${chunk.name}/index.js`;
},
},
},
},
});
I tried having a separate vite config for the content scripts to build it in one file. But, I was not successful
Here's what the config for that looks like:
import { resolve } from "path";
import { defineConfig } from "vite";
import copyContentStyle from "./utils/plugins/copy-content-style";
import { viteSingleFile } from "vite-plugin-singlefile";
const root = resolve(__dirname, "src");
const pagesDir = resolve(root, "pages");
const assetsDir = resolve(root, "assets");
const outDir = resolve(__dirname, "dist");
const publicDir = resolve(__dirname, "public");
const IS_DEV = process.env.DEV === "true";
export default defineConfig({
resolve: {
alias: {
"#src": root,
"#assets": assetsDir,
"#pages": pagesDir,
},
},
plugins: [copyContentStyle(), viteSingleFile()],
publicDir,
build: {
minify: !IS_DEV,
outDir,
sourcemap: IS_DEV,
emptyOutDir: IS_DEV,
rollupOptions: {
input: {
content: resolve(pagesDir, "content", "index.ts"),
},
output: {
dir: `src/pages/content`,
},
},
},
});
I ended up having a separate vite config for the content script, which looks like:
import { resolve } from "path";
import { defineConfig } from "vite";
import { viteSingleFile } from "vite-plugin-singlefile";
const root = resolve(__dirname, "src");
const pagesDir = resolve(root, "pages");
const outDir = resolve(__dirname, "dist", "src", "pages", "content");
const IS_DEV = process.env.DEV === "true";
export default defineConfig({
resolve: {
alias: {
"#src": root,
"#pages": pagesDir,
},
},
plugins: [viteSingleFile()],
build: {
copyPublicDir: false,
minify: !IS_DEV,
outDir,
sourcemap: IS_DEV,
emptyOutDir: IS_DEV,
rollupOptions: {
input: {
content: resolve(pagesDir, "content", "index.ts"),
},
output: {
entryFileNames: "index.js",
},
},
},
});
And, I run it all with:
"scripts": {
"build:general": "vite build",
"build:content": "vite build --config vite.contentScript-config.ts",
"build": "run-p build:*",
"dev:general": "vite build --watch --mode development",
"dev:content": "vite build --config vite.contentScript-config.ts --watch --mode development",
"dev": "run-p dev:*"
},

Unable to run lambda in docker image

I currently have an AWS Lambda that I've been working on that I would like to build and run from a docker image. I'm using the aws-lambda-node:16 image as my base image. But I can't seem to get the docker image to properly pick up the handler from my javascript file to run the lambda.
I have tested the lambda's execution outside the docker image with lambda-local and the lambda runs fine in my local environment. It just seems that something is up with the docker container.
My Dockerfile:
FROM amazon/aws-lambda-nodejs:16
COPY dist/blacklist-ips/app.js ${LAMBDA_TASK_ROOT}
COPY package.json pnpm-lock.yaml ${LAMBDA_TASK_ROOT}/
RUN npm i -g pnpm && pnpm install --production
CMD [ "app.handle" ]
My Webpack config:
import { resolve } from 'path';
import { default as webpack } from 'webpack';
import TerserPlugin from 'terser-webpack-plugin';
const config = (env: any, argv: any): webpack.Configuration => {
return {
mode: env.production ? 'production' : 'development',
entry: {
'blacklist-ips': resolve(__dirname, 'src', 'blacklist-ips', 'blacklist-ips.ts')
},
output: {
path: resolve(__dirname, 'dist'),
filename: '[name]/app.js',
libraryTarget: 'commonjs2'
},
devtool: false,
target: 'node',
externals: [
'#aws-sdk/client-cloudwatch-logs',
'#aws-sdk/client-wafv2',
'luxon',
'tslib'
],
resolve: {
extensions: [ '.ts', '.js', '.json' ]
},
module: {
rules: [
{
test: /.ts$/,
loader: 'ts-loader'
}
]
},
optimization: {
minimize: env.production,
minimizer: [
new TerserPlugin({
parallel: true,
terserOptions: {
mangle: false
}
})
]
}
}
}
export default config;
My handler function is being properly exported in the webpack bundle:
const handler = async () => {
...lambda logic
};
exports.handler = handler;
I'm stumped as to why it's not working correctly with the Docker container...
Your CMD is app.handle while your function name is handler. You should change the CMD to be app.handler.

Is there any way to make an executable file (.exe) from a Nuxt+Node project?

I have a NuxtJS project that requires a NodeJS program running behind for some functions and logic. The project structure is as follows:
api
assets
components
layouts
middleware
pages
plugins
server
static
store
nuxt.config.js
package.json
nuxt.config.js
module.exports = {
head: {
titleTemplate: '%s',
title: 'Project',
htmlAttrs: {
lang: 'en'
},
meta: [
{ charset: 'utf-8' },
{ name: 'viewport', content: 'width=device-width, initial-scale=1' },
{ hid: 'description', name: 'description', content: '' }
],
link: [
{ rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' }
]
},
css: [
'#/assets/css/main.scss'
],
plugins: [
],
components: true,
buildModules: [
'#nuxtjs/vuetify'
],
modules: [
'nuxt-socket-io',
'nuxt-i18n',
'#nuxtjs/axios',
'#nuxtjs/auth-next'
],
io: {
sockets: [
{
name: 'main',
url: process.env.APP_SERVER_URL,
default: true
}
]
},
i18n: {
locales: [
{
code: 'en',
file: 'en-US.js'
}
],
lazy: true,
langDir: 'lang/',
defaultLocale: 'en'
},
serverMiddleware: [
{ path: '/api', handler: '~/api/index.js' },
],
axios: {
baseURL: process.env.APP_SERVER_URL,
},
vuetify: {
customVariables: ['~/assets/variables.scss'],
theme: {
dark: true,
themes: {
dark: {},
light: {}
}
}
},
build: {
extend(config) {}
}
}
package.json
{
"name": "my-project",
"version": "1.0.0",
"private": true,
"scripts": {
"dev": "nodemon -w server -w nuxt.config.js server",
"build": "nuxt generate",
"start": "cross-env NODE_ENV=production node server",
"generate": "nuxt generate"
},
"dependencies": {
"#nuxtjs/auth-next": "5.0.0-1611574754.9020f2a",
"#nuxtjs/axios": "^5.12.5",
"body-parser": "^1.19.0",
"core-js": "^3.8.3",
"dotenv": "^8.2.0",
"express": "^4.17.1",
"http": "0.0.1-security",
"moment": "^2.29.1",
"nuxt": "^2.14.12",
"nuxt-i18n": "^6.18.0",
"nuxt-socket-io": "^1.1.14"
},
"devDependencies": {
"#nuxtjs/vuetify": "^1.11.3",
"cross-env": "^7.0.3",
"nodemon": "^2.0.7"
}
}
server/index.js
require('dotenv').config();
const isProd = process.env.NODE_ENV === 'production'
const http = require('http')
const app = require('express')()
const server = http.createServer(app)
const io = require('socket.io')(server)
const axios = require('axios')
const { Nuxt, Builder } = require('nuxt')
const config = require('../nuxt.config.js');
config.dev = !isProd;
const nuxt = new Nuxt(config)
const { host, port } = nuxt.options.server
if (config.dev) {
const builder = new Builder(nuxt)
builder.build()
} else {
nuxt.ready()
}
app.use(nuxt.render)
server.listen(port, () => {
console.log(`Server listening on http://${host}:${port}`)
});
// other logic
I need an exe that can be installed in other computers for running the Nodejs server and the Nuxt stuff, like I run the code by npm run dev or npm run build/start in the development computer locally.
I have tried nexe by running nexe -i server but not succeeded. Is there any other way for me to do that?
Thank you.
I think you can take a look at pm2. You can run node server and other stuff with that.
Compiling a Node.js Application into an .exe File
Two of the most commonly used packages used to compile JavaScript files into executables are:
nexe: It is a simple command-line utility that compiles your Node.js application into a single executable file. By default, it converts it into a Windows executable.
pkg: It is a Node.js package that can convert your Node.js app into several executable files for various operating systems (all at once) or of an individual operating system.
enter link description here

How to use Development Version of Reactjs with Webpack 4

This is my current webpack configuration. Its been a while since I've had to do this, and the last time I did it webpack 2 was just coming out. At that point there was a plugin that would allow me to define my output. Now that plugin is no longer valid.
What I need to do is use the development version of ReactJS but my builds keep building with the production version. So error handling is next to impossible since react removes a bulk of the errors in a production build.
const fs = require('fs');
const os = require('os');
const path = require('path');
const webpack = require('webpack');
const files = fs.readdirSync('./src/scripts/').filter(function (file) {
return path.extname(file) === '.js';
});
const entries = files.reduce(function (obj, file, index) {
const key = path.basename(file, '.js');
obj[key] = [
'./src/scripts/' + key
];
return obj;
}, {});
entries.hotreload = 'react-hot-loader/patch';
console.log(argv.mode);
module.exports = {
mode: 'development',
entry: entries,
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
use: ['babel-loader']
}
]
},
resolve: {
extensions: ['*', '.js', '.jsx']
},
output: {
path: __dirname + '/dist/scripts',
publicPath: '/',
filename: '[name].js'
},
plugins: [
new webpack.HotModuleReplacementPlugin()
],
devServer: {
contentBase: './dist/scripts',
hot: true
}
};
This is also how I start webpack webpack-dev-server --config ./webpack.config.js --mode development which doesn't seem to do me any good.
Well, I create a script to run the webpack server. This is how I start the dev server npm start.
Here is my scripts:
"scripts": {
"dev": "webpack --mode development",
"start": "webpack-dev-server",
"build": "cross-env NODE_ENV=production webpack-dev-server --client-log-level none --color --compress"
},
And here my webpack.config.js:
const modoDev = process.env.NODE_ENV != "production";
const webpack = require('webpack');
const ExtractTextPlugin = require('mini-css-extract-plugin');
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
const OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin');
const path = require('path');
module.exports = {
mode: modoDev ? 'development' : 'production',
entry: './src/index.jsx',
output: {
path: __dirname + '/public',
filename: './app.js',
publicPath: '/'
},
optimization: {
minimizer: [
new UglifyJsPlugin({
cache: true,
parallel: true
}),
new OptimizeCssAssetsPlugin({})
]
},
devServer: {
host: '0.0.0.0',
port: 8080,
contentBase: './public',
historyApiFallback: {
index: "/"
},
},
resolve: {
extensions: ['*', '.js', '.jsx'],
alias: {
modules: path.resolve(__dirname + '/node_modules/')
}
},
plugins: [new ExtractTextPlugin({
filename: 'app.css'
}), new webpack.ProvidePlugin({
$: "jquery",
jQuery: "jquery"
})],
module: {
rules: [{
test: /.js[x]?$/,
exclude: /node_modules/,
use: {
loader: "babel-loader"
}
},
{
test: /\.(sa|sc|c)ss$/,
use: [ExtractTextPlugin.loader, 'css-loader', 'sass-loader']
}, {
test: /\.woff|.woff2|.ttf|.eot|.svg|.png|.jpg*.*$/,
use: ['file-loader']
},
],
}
};

webpack --json: Error: 'output.filename' is required

I have a valid webpack.config.js that I use constantly for development, with the following content:
var path = require('path')
const merge = require('webpack-merge');
const NpmInstallPlugin = require('npm-install-webpack2-plugin');
var webpack = require('webpack')
var ManifestPlugin = require('webpack-manifest-plugin')
var InlineChunkManifestHtmlWebpackPlugin = require('inline-chunk-manifest-html-webpack-plugin')
var WebpackChunkHash = require("webpack-chunk-hash")
var HtmlWebpackPlugin = require('html-webpack-plugin')
var ExtractTextPlugin = require('extract-text-webpack-plugin')
var CleanWebpackPlugin = require('clean-webpack-plugin')
const proxyTarget = 'http://localhost:2246/'
const visitPort = '8056'
const isMinimize =false
const outputFolderName = ''
const TARGET = process.env.npm_lifecycle_event;
isDebug = process.env.NODE_ENV === 'production' ?
true :
false;
const common = {
entry: './src/app.js',
devServer: {
hot: true,
historyApiFallback: true,
noInfo: true
},
performance: {
hints: false
},
output: {
path: path.resolve(__dirname, './dist'),
publicPath: '/dist/',
filename: 'build.js'
},
resolve: {
alias: {
vue: 'vue/dist/vue.js'
}
},
module: {
rules: [
{
test: /\.vue$/,
loader: 'vue-loader',
options: {
loaders: {
// Since sass-loader (weirdly) has SCSS as its default parse mode, we map
// the "scss" and "sass" values for the lang attribute to the right configs here.
// other preprocessors should work out of the box, no loader config like this necessary.
'scss': 'vue-style-loader!css-loader!sass-loader',
'sass': 'vue-style-loader!css-loader!sass-loader?indentedSyntax'
}
// other vue-loader options go here
}
},
{
test: /\.js$/,
loader: 'babel-loader',
exclude: /node_modules/
},
{
test: /\.(png|jpg|gif|svg)$/,
loader: 'file-loader',
options: {
name: '[name].[ext]?[hash]'
}
},
{
test: /\.(woff|woff2|ttf|eot)(\?\S*)?$/,
loader: 'file-loader',
options: {
name: '[name].[ext]?[hash]'
}
}
]
},
resolve : {
alias: {
'vue$': 'vue/dist/vue'
}
}
}
if (process.env.NODE_ENV === 'production') {
module.exports.plugins = [
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: '"production"'
}
}),
new webpack.optimize.UglifyJsPlugin({
compress: {
warnings: false
}
})
]
} else {
module.exports.devtool = '#source-map'
}
if(TARGET === 'build') {
module.exports = merge(common,
{
devtool: 'source-map',
});
}
if(TARGET === "dev-server") {
module.exports = merge(common, {
devtool: 'cheap-module-eval-source-map',
devServer: {
historyApiFallback: true,
hot: true,
inline: true,
stats: true,
noInfo: true,
quiet: true,
stats: 'errors-only',
// host: process.env.HOST,
port: 3001
},
plugins: [
new webpack.HotModuleReplacementPlugin(),
new NpmInstallPlugin({
save: true // --save
})
]
});
}
The following npm run commands are in package.json and all of the commands run successfully
"scripts": {
"dev-server": "cross-env NODE_ENV=development webpack-dev-server",
"dev": "cross-env NODE_ENV=development electron ./",
"build": "cross-env NODE_ENV=production webpack --progress --profile --colors",
"start": "cross-env NODE_ENV=production electron ./",
"package": "npm run build; npm run package-osx;
}
Problem
I am trying to use the webpack-bundle-size-analyzer to check the bundled packages. The following command
$ webpack --json | webpack-bundle-size-analyzer
produced this error
/usr/local/lib/node_modules/webpack/bin/convert-argv.js:507
throw new Error("'output.filename' is required, either in config file or as --output-filename");
^
Error: 'output.filename' is required, either in config file or as --output-filename
at processOptions (/usr/local/lib/node_modules/webpack/bin/convert-argv.js:507:11)
at processConfiguredOptions (/usr/local/lib/node_modules/webpack/bin/convert-argv.js:150:4)
at module.exports (/usr/local/lib/node_modules/webpack/bin/convert-argv.js:112:10)
at yargs.parse (/usr/local/lib/node_modules/webpack/bin/webpack.js:171:41)
at Object.Yargs.self.parse (/usr/local/lib/node_modules/webpack/node_modules/yargs/yargs.js:533:18)
at Object.<anonymous> (/usr/local/lib/node_modules/webpack/bin/webpack.js:152:7)
at Module._compile (module.js:573:30)
at Object.Module._extensions..js (module.js:584:10)
at Module.load (module.js:507:32)
at tryModuleLoad (module.js:470:12)
at Function.Module._load (module.js:462:3)
at Function.Module.runMain (module.js:609:10)
at startup (bootstrap_node.js:158:16)
at bootstrap_node.js:598:3
Error: The input is not valid JSON.
Check that:
- You passed the '--json' argument to 'webpack'
- There is no extra non-JSON content in the output, such as log messages.
The parsing error was:
SyntaxError: Unexpected end of JSON input
webpack: 3.6.0
webpack-bundle-size-analyzer: 2.7.0
Additional Notes
I have validated the webpack.config.js file, at the root of project directory
No spelling mistakes in the webpack.config.js file as far as I can see
I just need a simple JSON output from webpack to feed to webpack-bundle-size-analyzer

Resources