Webpack build gives javascript memory heap error - node.js

I have my Webpack configuration as follows for a NodeJS project with TypeScript. When it is compiling it gives the "JavaScript memory Heap" error in the terminal. I usually increase the memory limit in the local terminal in order to do have the output build folder. But this is not the case with the server as it has some memory limitations. Can someone help me to sort out this issue either with the parallel build or any memory optimization technics.
This is my package.json.
"devDependencies": {
"fs": "^0.0.1-security",
"glob": "^8.0.3",
"path": "^0.12.7",
"ts-loader": "^9.4.1",
"ts-node": "^10.9.1",
"typescript": "^4.9.3",
"webpack": "^5.75.0",
"webpack-cli": "^5.0.0",
"zip-webpack-plugin": "^4.0.1"
},
"dependencies": {
"#types/aws-lambda": "^8.10.109",
"#types/tedious": "^4.0.9",
"aws-sdk": "^2.1257.0",
"axios": "^1.2.0",
"jsonwebtoken": "^8.5.1",
"node-tls": "^0.10.2",
"sequelize": "^6.28.0",
"tedious": "^15.1.2"
}
as per the above dependencies I use Webpack 5.
This is the Webpack.config.js
const webpack = require('webpack');
const path = require("path");
const glob = require("glob");
const ZipPlugin = require("zip-webpack-plugin");
const tedious = require("tedious");
const TerserPlugin = require('terser-webpack-plugin');
const entries = () => {
const src = path.resolve(__dirname, "functions");
const files = glob.sync(src + "/**/*");
return files
.filter((f) => f.indexOf("index.ts") > -1)
.map((f) => "./" + path.relative(path.resolve(__dirname), f));
};
const getBundleName = (path) =>
path
.substring("./functions/".length, path.lastIndexOf("/"))
.replaceAll("/", "-")
.toLowerCase();
const config = () => {
let modules = [];
const files = entries();
files.forEach((f) => {
console.log(f)
const bundleName = getBundleName(f);
const outputPath = path.resolve(
__dirname,
"dist/" +
bundleName.substring(0, bundleName.lastIndexOf("-")) +
"/" +
bundleName.substring(bundleName.lastIndexOf("-") + 1)
);
const moduleConfig = {
name: bundleName,
entry: f,
output: {
path: outputPath,
filename: "index.js",
libraryTarget: "commonjs",
clean: true,
},
module: {
rules: [
{
test: /\.ts?$/,
use: "ts-loader",
exclude: [/node_modules/, /\.test.ts?$/],
},
],
},
target: "node",
plugins: [
new ZipPlugin({
path: "./",
filename: `${bundleName}.zip`,
}),
new webpack.ids.DeterministicChunkIdsPlugin({
maxLength: 5,
}),
],
optimization: {
minimizer: [
new TerserPlugin({
parallel: true,
}),
],
chunkIds: 'named',
concatenateModules: true,
emitOnErrors: true,
mangleWasmImports: true,
moduleIds: 'deterministic',
runtimeChunk: {
name: 'runtime',
},
sideEffects: 'flag',
usedExports: 'global',
},
resolve: {
mainFields: ["main"],
extensions: [".tsx", ".ts", ".js", ".json", "..."],
alias: {'tedious': path.join(__dirname, './node_modules/tedious')},
},
resolveLoader: {
modules: ["node_modules"],
},
externals: ['pg', 'sqlite3', 'tedious', 'pg-hstore'],
/*devtool: "source-map",*/
};
modules.push(moduleConfig);
});
return modules;
};
module.exports = config();
I am expecting to understand the issues or any improvements of my Webpack configuration for the memory optimization for the code build with this nodejs TS project.

Related

monaco web editor, language functionality don't working

I try to recreate an existing monaco+react+typescript project to my own goals. And it's not working, unfortunately. Language functionalities don't work. When I tried to throw alerts from the setupLanguage function it's working on getWorkerUrl function only. But don't work for the monaco.languages.onLanguage event processor.
May I ask you to show me the point where I'm wrong?
Regards, vladimir
P.s. Code are available on https://github.com/vladimirkozhaev/monaco-web-editor-new-edition
This is my setup.ts
import * as monaco from "monaco-editor-core";
import { languageExtensionPoint, languageID } from "./config";
import { richLanguageConfiguration, monarchLanguage } from "./TodoLang";
import { TodoLangWorker } from "./todoLangWorker";
import { WorkerManager } from "./WorkerManager";
import DiagnosticsAdapter from "./DiagnosticsAdapter";
import TodoLangFormattingProvider from "./TodoLangFormattingProvider";
export function setupLanguage() {
(window as any).MonacoEnvironment = {
getWorkerUrl: function (moduleId, label) {
if (label === languageID)
return "./todoLangWorker.js";
return './editor.worker.js';
}
}
monaco.languages.register(languageExtensionPoint);
monaco.languages.onLanguage(languageID, () => {
monaco.languages.setMonarchTokensProvider(languageID, monarchLanguage);
monaco.languages.setLanguageConfiguration(languageID, richLanguageConfiguration);
const client = new WorkerManager();
const worker: WorkerAccessor = (...uris: monaco.Uri[]): Promise<TodoLangWorker> => {
return client.getLanguageServiceWorker(...uris);
};
//Call the errors provider
new DiagnosticsAdapter(worker);
monaco.languages.registerDocumentFormattingEditProvider(languageID, new TodoLangFormattingProvider(worker));
});
}
export type WorkerAccessor = (...uris: monaco.Uri[]) => Promise<TodoLangWorker>;
This is my package.json
{
"name": "todolangeditor",
"version": "1.0.0",
"description": "TodoLang editor",
"license": "UNLICENSED",
"scripts": {
"test": "jest -c jest.config.unit.js",
"start": "webpack-dev-server",
"antlr4ts": "antlr4ts ./ExpressionsParserGrammar.g4 -visitor -o ./src/ANTLR"
},
"dependencies": {
"antlr4ts": "0.5.0-alpha.4",
"monaco-editor-core": "0.18.1",
"react": "16.8.6",
"react-dom": "16.8.6"
},
"devDependencies": {
"#types/react": "16.8.12",
"source-map-loader": "^1.0.0",
"#types/react-dom": "16.8.3",
"antlr4ts-cli": "0.5.0-alpha.4",
"css-loader": "3.3.0",
"html-webpack-plugin": "3.2.0",
"style-loader": "1.0.1",
"ts-loader": "5.3.3",
"typescript": "^4.8",
"webpack": "4.29.6",
"webpack-cli": "3.3.0",
"webpack-dev-server": "3.2.1",
"ts-jest": "^29.0.3",
"#types/jest":"29.0.3"
}
}
This is my webpack.config.js
const path = require('path');
const htmlWebpackPlugin = require('html-webpack-plugin');
const { SourceMapDevToolPlugin } = require("webpack");
module.exports = {
mode: 'development',
entry: {
app: './src/index.tsx',
"editor.worker": 'monaco-editor-core/esm/vs/editor/editor.worker.js',
"todoLangWorker": './src/todo-lang/todolang.worker.ts'
},
output: {
globalObject: 'self',
filename: (chunkData) => {
switch (chunkData.chunk.name) {
case 'editor.worker':
return 'editor.worker.js';
case 'todoLangWorker':
return "todoLangWorker.js"
default:
return 'bundle.[hash].js';
}
},
path: path.resolve(__dirname, 'dist')
},
resolve: {
extensions: ['.ts', '.tsx', '.js', '.jsx', '.css']
},
module: {
rules: [
{
test: /\.tsx?/,
loader: 'ts-loader'
},
{
test: /\.css/,
use: ['style-loader', 'css-loader']
},
{
test: /\.js$/,
enforce: 'pre',
use: ['source-map-loader']
}
]
},
plugins: [
// new SourceMapDevToolPlugin({
// filename: "[file].map"
// }),
new htmlWebpackPlugin({
template: './src/index.html'
})
]
}
This is my index.tsx
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import {setupLanguage} from "./todo-lang/setup";
import { Editor } from './components/Editor/Editor';
import { languageID } from './todo-lang/config';
import { parseAndGetSyntaxErrors, parseAndGetASTRoot } from './language-service/Parser';
setupLanguage();
const App = () => <Editor language={languageID}></Editor>;
ReactDOM.render(<App/>, document.getElementById('container'));

unhandledRejection The "path" argument must be of type string or an instance of Buffer or URL. Received undefined - Nuxtjs

When I try to build or run nuxi dev to start my application for development this error comes up and application don't work properly.
I deleted all lock files, removed module folder and run yarn install but this is still there,
This is the exception trace info from compiler.
at readFileSync (node:fs:453:35)
at extractMeta (node_modules\nuxt-route-meta\dist\index.js:52:51)
at parseRoutes (node_modules\nuxt-route-meta\dist\index.js:149:57)
at /D:/Frontend/nuxt2/node_modules/#nuxt/kit/dist/index.mjs:477:37
at /D:/Frontend/nuxt2/node_modules/hookable/dist/index.mjs:39:70
at processTicksAndRejections (node:internal/process/task_queues:96:5)
at async Object.getContents (/D:/Frontend/nuxt2/node_modules/nuxt3/dist/chunks/index.mjs:348:9)
at async /D:/Frontend/nuxt2/node_modules/nuxt3/dist/chunks/index.mjs:1338:22
at async Promise.all (index 16)
Here is the .env file
BASE_URL=http://localhost:8000
ECHO_PORT=
HOSTNAME=http://localhost:3000
STRIPE_KEY=x
ALGOLIA_APP_ID=y
ALGOLIA_API_KEY=z
And here is the nuxt.config.ts file content.
import getSiteMeta from './utils/getSiteMeta'
import { cloneDeep } from 'lodash'
const meta = getSiteMeta()
// https://v3.nuxtjs.org/docs/directory-structure/nuxt.config
export default defineNuxtConfig({
ssr: false,
// server: {
// host: process.env.HOST || 'localhost' // default: localhost
// },
sitemap: [
{
hostname: process.env.BASE_URL || 'http://localhost:3000',
path: '/sitemap.xml',
gzip: true,
},
],
// Global page headers (https://go.nuxtjs.dev/config-head)
head: {
htmlAttrs: {
lang: 'en-GB',
},
title:
'Family Tree 365 - Start your family tree today - free! Your first tree is 100% free. Sign-up to begin your genealogy journey today!',
meta: [
...meta,
{ charset: 'utf-8' },
{ name: 'HandheldFriendly', content: 'True' },
{ name: 'viewport', content: 'width=device-width, initial-scale=1' },
{ property: 'og:site_name', content: 'Family Tree 365' },
{
hid: 'description',
name: 'description',
content:
'Our user-friendly yet powerful platform lets you create your own family tree the quick and easy way. No technical knowledge is required. Start your family tree today - free!',
},
{ property: 'og:image:width', content: '2500' },
{ property: 'og:image:height', content: '780' },
{ name: 'twitter:site', content: '#familytree365' },
{ name: 'twitter:card', content: 'summary_large_image' },
],
link: [
{ rel: 'icon', href: '/favicon.ico' },
{
hid: 'canonical',
rel: 'canonical',
href: process.env.BASE_URL,
},
],
},
// Global CSS: https://go.nuxtjs.dev/config-css
// css: ["~/assets/style/enso.scss", "animate.css/animate.compat.css"],
css: [
'animate.css/animate.compat.css',
'~/assets/css/base.css',
'~/assets/style/enso.scss',
'~/assets/css/fontawesome.min.css',
],
router: {
middleware: 'auth'
},
// Plugins to run before rendering page: https://go.nuxtjs.dev/config-plugins
plugins: [
'~/plugins/bootEnums.js',
'~/plugins/i18n.js',
'~/plugins/pRoute.js',
'~/plugins/filters.js',
'~/plugins/numberFormat.js',
'~/plugins/shortNumber.js',
'~/plugins/toastr.js',
'~/plugins/fontawesome.js',
'~/plugins/themesSettingRegister.js',
'~/plugins/bookmarksSettingRegister.js',
'~/plugins/tutorialSettingRegister.js',
'~/plugins/notificationsRegister.js',
'~/plugins/localisationRegister.js',
'~/plugins/ioRegister.js',
'~/plugins/tasksNavbarRegister.js',
'~/plugins/usersRegister.js',
'~/plugins/Validator.js',
'~/plugins/date-fns/format.js',
'~/plugins/date-fns/formatDistance.js',
'~/plugins/vue-select.js',
'~/plugins/vuelidate.js',
'~/plugins/vue-gtag.client.js',
//'~/plugins/echo.js',
"~/plugins/vue-fb-customer-chat.js",
{src: '~/plugins/vue-stripe.js', ssr: false},
],
// Auto import components: https://go.nuxtjs.dev/config-components
// components: true,
// Modules for dev and build (recommended): https://go.nuxtjs.dev/config-modules
buildModules: [
// https://go.nuxtjs.dev/eslint
// "#nuxtjs/eslint-module",
'#nuxtjs/fontawesome',
'#nuxtjs/router-extras',
'#nuxtjs/vuetify',
],
// Modules: https://go.nuxtjs.dev/config-modules
modules: [
// https://go.nuxtjs.dev/axios
'#nuxtjs/axios',
'nuxt-vuex-router-sync',
'nuxt-route-meta',
],
fontawesome: {
icons: {
solid: true,
brands: true,
},
},
nuxtContentAlgolia: {
appId: process.env.ALGOLIA_APP_ID,
apiKey: process.env.ALGOLIA_API_KEY,
paths: [
{
name: 'articles',
index: 'articles',
fields: ['title', 'description', 'bodyPlainText'],
},
],
},
publicRuntimeConfig: {
axios: {
browserBaseURL: process.env.BASE_URL || 'http://localhost:3000',
proxyHeaders: false,
},
appEnv: process.env.APP_ENV || 'production',
},
env: {
STRIPE_PK: process.env.STRIPE_KEY,
baseUrl: process.env.BASE_URL ||'http://localhost:3000',
},
// Axios module configuration: https://go.nuxtjs.dev/config-axios
axios: {
proxyHeaders: false,
proxy: true,
credentials: true,
},
proxy: {
'/api/': process.env.BASE_URL || 'http://localhost:8000',
'/broadcasting/': process.env.BASE_URL || 'http://localhost:8000',
},
// Build Configuration: https://go.nuxtjs.dev/config-build
build: {
filenames: {
app: ({ isDev }) => (isDev ? '[name].js' : '[chunkhash].js'),
chunk: ({ isDev }) => (isDev ? '[name].js' : '[chunkhash].js'),
css: ({ isDev }) => (isDev ? '[name].css' : '[contenthash].css'),
img: ({ isDev }) => (isDev ? '[path][name].[ext]' : 'img/[hash:7].[ext]'),
font: ({ isDev }) =>
isDev ? '[path][name].[ext]' : 'fonts/[hash:7].[ext]',
video: ({ isDev }) =>
isDev ? '[path][name].[ext]' : 'videos/[hash:7].[ext]',
},
transpile: [
'#enso-ui/strings',
'vee-validate/dist/rules',
'#enso-ui/enums',
'#sentry/browser',
'#sentry/integrations',
'#enso-ui/sentry',
'#enso-ui/route-mapper',
'd3-dag',
],
extend(config) {
const isScssRule = (rule) => rule.test.toString() === '/\\.scss$/i'
config.module.rules.forEach((rule) => {
if (isScssRule(rule)) {
const normalRule = rule.oneOf.find(
({ resourceQuery, test }) =>
resourceQuery === undefined && test === undefined
)
const lazyRule = cloneDeep(normalRule)
lazyRule.test = /\.lazy\.scss$/
const idx = lazyRule.use.findIndex(({ loader }) =>
loader.includes('vue-style-loader')
)
if (idx > -1) {
lazyRule.use.splice(idx, 1, {
loader: 'style-loader',
options: {
injectType: 'lazyStyleTag',
insert: function insertAtTop(element) {
const parent = document.querySelector('head')
parent.insertBefore(element, parent.firstChild)
},
},
})
}
rule.oneOf.push(lazyRule)
}
})
// const scssRules = config.module.rules.find('scss').oneOfs;
// const normalRule = scssRules.store.get('normal');
// const lazyRule = config.module.rules.find('scss').oneOf('scss-lazy');
// normalRule.uses.values().forEach(use => {
// if (use.name !== 'vue-style-loader') {
// lazyRule.use(use.name).merge(use.entries());
// return;
// }
// lazyRule.use('style-loader')
// .loader('style-loader')
// .options({
// injectType: 'lazyStyleTag',
// insert: function insertAtTop(element) {
// const parent = document.querySelector('head');
// parent.insertBefore(element, parent.firstChild);
// },
// });
// });
// lazyRule.test(/\.lazy\.scss$/);
// scssRules.store.delete('normal', 'scss-lazy');
// scssRules.store.set('scss-lazy', lazyRule);
// scssRules.store.set('normal', normalRule);
},
},
})
Have a look at my package.json file
{
"private": true,
"scripts": {
"dev": "nuxi dev",
"build": "nuxi build",
"start": "node .output/server/index.mjs"
},
"devDependencies": {
"#fortawesome/free-brands-svg-icons": "^6.0.0",
"#nuxtjs/fontawesome": "^1.1.2",
"#nuxtjs/vuetify": "^1.12.3",
"nuxt3": "^3.0.0-27444169.120ee4f"
},
"dependencies": {
"#enso-ui/bulma": "^5.0.7",
"#enso-ui/charts": "^4.0.0",
"#enso-ui/laravel-validation": "^2.0.6",
"#enso-ui/transitions": "^2.0.11",
"#fortawesome/fontawesome-svg-core": "^1.3.0",
"#fortawesome/free-solid-svg-icons": "^6.0.0",
"#nuxtjs/axios": "^5.13.6",
"#nuxtjs/router-extras": "^1.1.1",
"#nuxtjs/style-resources": "^1.2.1",
"chart": "^0.1.2",
"chart.js": "^2.9.4",
"node-sass": "^7.0.1",
"nuxt-route-meta": "^2.3.4",
"nuxt-vuex-router-sync": "^0.0.3",
"postcss": "^8.2.15",
"resolve": "1.20.0",
"vue": "^3.2.31",
"vue-chartjs": "^3.5.1",
"vue-gtag-next": "^1.14.0",
"vue-loading-overlay": "5.0",
"vuex": "^4.0.2"
}
}

Webpack dev server - DeprecationWarning: Using 'compiler' as the first argument is deprecated

I upgraded from webpack dev server 3.11.2 to 4.4.0 and I get these deprecated warnings on npm run dev:
"dev": "webpack serve --config webpack.dev.js",
(node:33156) [DEP_WEBPACK_DEV_SERVER_CONSTRUCTOR] DeprecationWarning: Using 'compiler' as the first argument is deprecated. Please use 'options' as the first argument and 'compiler' as the second argument. (node:33156) [DEP_WEBPACK_DEV_SERVER_LISTEN] DeprecationWarning: 'listen' is deprecated. Please use async 'start' or 'startCallback' methods
I don't even have new WebpackDevServer in the configs to be able to change the order of the options and compiler, nor am I using a listen(). I don't get why I am getting these warnings or how to resolve them.
Does anyone know how to resolve these warnings? Thanks!
webpack.common.js
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const env = process.env.NODE_ENV || 'development';
module.exports = {
output: {
path: path.resolve(__dirname, `dist/${env}`),
filename: '[name]-[fullhash].js',
publicPath: '/', // used for routing
},
resolve: {
modules: [path.resolve(__dirname, './src'), 'node_modules'],
alias: {
components: path.resolve(__dirname, './src/components'),
store: path.resolve(__dirname, './src/store'),
helpers: path.resolve(__dirname, './src/helpers'),
constants: path.resolve(__dirname, './src/constants'),
config: path.resolve(__dirname, './src/config'),
},
fallback: {
fs: false,
tls: false,
net: false,
path: false,
zlib: false,
http: false,
https: false,
stream: false,
crypto: false,
},
},
module: {
rules: [
{
test: /\.(js|jsx)$/,
use: {
loader: 'babel-loader',
},
exclude: [/node_modules/],
},
{
test: /\.(png|svg|jpg|jpeg|gif|ico)$/,
use: {
loader: 'url-loader',
},
},
{
test: /\.(css|scss|sass)$/,
use: [MiniCssExtractPlugin.loader, 'css-loader'],
},
],
},
plugins: [
new HtmlWebpackPlugin({
hash: true, // cache busting
template: 'public/index.html',
favicon: './public/favicon.ico',
}),
// creates a separate style.css file instead of adding the styles to the bundle.js
new MiniCssExtractPlugin({
filename: '[name].[fullhash].css',
chunkFilename: '[id].[fullhash].css',
}),
new CleanWebpackPlugin({ cleanAfterEveryBuildPatterns: [`dist/${env}`] }),
new CopyWebpackPlugin({
patterns: [{ from: 'src/server', to: 'server' }],
}),
],
};
webpack.dev.js
require('dotenv-override').config({ override: true });
const express = require('express');
const { merge } = require('webpack-merge');
const webpack = require('webpack');
const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer');
const common = require('./webpack.common');
const setupProxy = require('./src/server/proxy');
const loggingEndpoint = require('./src/server/logging/loggingEndpoint');
module.exports = merge(common, {
mode: 'development',
devServer: {
// inline: true, // refreshes the page on change
open: true,
port: 8081,
historyApiFallback: {
index: '/', // used for routing (404 response), and address bar routing
},
onBeforeSetupMiddleware: (server) => {
setupProxy(server.app);
server.app.use(express.json());
server.app.use(express.urlencoded({ extended: true }));
server.app.post('/logging', loggingEndpoint);
},
},
plugins: [
new webpack.DefinePlugin({
'process.env.NODE_ENV': JSON.stringify('development'),
}),
new BundleAnalyzerPlugin({
analyzerMode: 'disabled', // server mode displays report
}),
],
devtool: 'cheap-module-source-map',
});
I had to upadte other webpack packages and that did it ;)
Old:
"webpack-bundle-analyzer": "^4.4.2",
"webpack-cli": "^4.7.0",
"webpack-dev-server": "^4.4.0",
"webpack-merge": "^5.7.3"
New:
"webpack-bundle-analyzer": "^4.5.0",
"webpack-cli": "^4.9.1",
"webpack-dev-server": "^4.4.0",
"webpack-merge": "^5.8.0"
So just update everything and that did the trick.
Follow the steps under
Solve Option & Compiler https://github.com/heartexlabs/label-studio-frontend/pull/296/commits/ded728c002d510d00d386b5cb5fc84feb977dbad
Solve Listen https://github.com/heartexlabs/label-studio-frontend/pull/296/commits/4305393e86856a19d1e6d3ee7677aa4abbbf4071
Main thread is under https://github.com/heartexlabs/label-studio-frontend/pull/296

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

Worker Script Failing to Load for Vue Webpack Built App

I deployed a Node application to CouchDB that I developed and built from a Vue Webpack template. One of the modules I rely on, pdfjs-dist, relies on a worker.
After running npm run build and getting my output in dist, I copy the output files to couchapp to deploy them to CouchDB. I get no errors during deployment and the site looks fine once it's up.
However, when I try doing something that requries pdfjs-dist, I get the error:
NetworkError: Failed to load worker script at
"http://.../docuapp/documentation/_design/uploads/static/js/app.4eb1aecbadc78360a76e.worker.js"
(unbekannt)
Error: Loading chunk 0 failed.
Stack-Trace:
u#http://.../docuapp/documentation/_design/uploads/static/js/manifest.a6f78538bddeebdefd4a.js:1:957
manifest.a6f78538bddeebdefd4a.js:1:1378
Error: Loading chunk 0 failed. manifest.a6f78538bddeebdefd4a.js:1:957
So I check out the url that's failing to load, and the document is missing. But when I remove the worker part of the url, i.e.
http://.../docuapp/documentation/_design/uploads/static/js/app.4eb1aecbadc78360a76e.js
This page loads, and I'm guessing that's the resource that's needed.
Does anyone have any guesses as to what's going wrong here?
Here's my package.json
{
"name": "docu-back",
"version": "1.0.0",
"description": "A Vue.js project",
"author": "",
"private": true,
"scripts": {
"dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js",
"start": "npm run dev",
"build": "node build/build.js"
},
"dependencies": {
"element-ui": "^2.0.11",
"mime-types": "^2.1.17",
"nano": "^6.4.2",
"node-dir": "^0.1.17",
"pdfjs-dist": "^2.0.332",
"querystring-browser": "^1.0.4",
"vue": "^2.5.2",
"vue-awesome": "^2.3.4",
"vue-router": "^3.0.1"
},
"devDependencies": {
"autoprefixer": "^7.1.2",
"babel-core": "^6.22.1",
"babel-helper-vue-jsx-merge-props": "^2.0.3",
"babel-loader": "^7.1.1",
"babel-plugin-syntax-jsx": "^6.18.0",
"babel-plugin-transform-runtime": "^6.22.0",
"babel-plugin-transform-vue-jsx": "^3.5.0",
"babel-preset-env": "^1.3.2",
"babel-preset-stage-2": "^6.22.0",
"chalk": "^2.0.1",
"copy-webpack-plugin": "^4.0.1",
"css-loader": "^0.28.0",
"extract-text-webpack-plugin": "^3.0.0",
"file-loader": "^1.1.4",
"friendly-errors-webpack-plugin": "^1.6.1",
"html-webpack-plugin": "^2.30.1",
"node-notifier": "^5.1.2",
"optimize-css-assets-webpack-plugin": "^3.2.0",
"ora": "^1.2.0",
"portfinder": "^1.0.13",
"postcss-import": "^11.0.0",
"postcss-loader": "^2.0.8",
"postcss-url": "^7.2.1",
"rimraf": "^2.6.0",
"semver": "^5.3.0",
"shelljs": "^0.7.6",
"uglifyjs-webpack-plugin": "^1.1.1",
"url-loader": "^0.5.8",
"vue-loader": "^13.3.0",
"vue-style-loader": "^3.0.1",
"vue-template-compiler": "^2.5.2",
"webpack": "^3.6.0",
"webpack-bundle-analyzer": "^2.9.0",
"webpack-dev-server": "^2.11.1",
"webpack-merge": "^4.1.0"
},
"engines": {
"node": ">= 6.0.0",
"npm": ">= 3.0.0"
},
"browserslist": [
"> 1%",
"last 2 versions",
"not ie <= 8"
]
}
build/build.js
'use strict'
require('./check-versions')()
process.env.NODE_ENV = 'production'
const ora = require('ora')
const rm = require('rimraf')
const path = require('path')
const chalk = require('chalk')
const webpack = require('webpack')
const config = require('../config')
const webpackConfig = require('./webpack.prod.conf')
const spinner = ora('building for production...')
spinner.start()
rm(path.join(config.build.assetsRoot, config.build.assetsSubDirectory), err => {
if (err) throw err
webpack(webpackConfig, (err, stats) => {
spinner.stop()
if (err) throw err
process.stdout.write(stats.toString({
colors: true,
modules: false,
children: false, // If you are using ts-loader, setting this to true will make TypeScript errors show up during build.
chunks: false,
chunkModules: false
}) + '\n\n')
if (stats.hasErrors()) {
console.log(chalk.red(' Build failed with errors.\n'))
process.exit(1)
}
console.log(chalk.cyan(' Build complete.\n'))
console.log(chalk.yellow(
' Tip: built files are meant to be served over an HTTP server.\n' +
' Opening index.html over file:// won\'t work.\n'
))
})
})
build/webpack.base.conf.js
const path = require('path')
const utils = require('./utils')
const config = require('../config')
const vueLoaderConfig = require('./vue-loader.conf')
function resolve (dir) {
return path.join(__dirname, '..', dir)
}
module.exports = {
context: path.resolve(__dirname, '../'),
entry: {
app: './src/main.js'
},
output: {
path: config.build.assetsRoot,
filename: '[name].js',
publicPath: process.env.NODE_ENV === 'production'
? config.build.assetsPublicPath
: config.dev.assetsPublicPath
},
resolve: {
extensions: ['.js', '.vue', '.json'],
alias: {
'vue$': 'vue/dist/vue.esm.js',
querystring: 'querystring-browser',
'#': resolve('src'),
'_qs': 'querystring-browser'
}
},
module: {
rules: [
{
test: /\.vue$/,
loader: 'vue-loader',
options: vueLoaderConfig
},
{
test: /\.js$/,
loader: 'babel-loader',
include: [resolve('src'), resolve('test'), resolve('node_modules/webpack-dev-server/client')]
},
{
test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
loader: 'url-loader',
options: {
limit: 10000,
name: utils.assetsPath('img/[name].[hash:7].[ext]')
}
},
{
test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/,
loader: 'url-loader',
options: {
limit: 10000,
name: utils.assetsPath('media/[name].[hash:7].[ext]')
}
},
{
test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
loader: 'url-loader',
options: {
limit: 10000,
name: utils.assetsPath('fonts/[name].[hash:7].[ext]')
}
}
]
},
node: {
// prevent webpack from injecting useless setImmediate polyfill because Vue
// source contains it (although only uses it if it's native).
setImmediate: false,
// prevent webpack from injecting mocks to Node native modules
// that does not make sense for the client
dgram: 'empty',
fs: 'empty',
net: 'empty',
tls: 'empty',
child_process: 'empty'
}
}
build/webpack.dev.conf.js
const utils = require('./utils')
const webpack = require('webpack')
const config = require('../config')
const merge = require('webpack-merge')
const path = require('path')
const baseWebpackConfig = require('./webpack.base.conf')
const CopyWebpackPlugin = require('copy-webpack-plugin')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin')
const portfinder = require('portfinder')
const HOST = process.env.HOST
const PORT = process.env.PORT && Number(process.env.PORT)
const devWebpackConfig = merge(baseWebpackConfig, {
module: {
rules: utils.styleLoaders({ sourceMap: config.dev.cssSourceMap, usePostCSS: true })
},
// cheap-module-eval-source-map is faster for development
devtool: config.dev.devtool,
// these devServer options should be customized in /config/index.js
devServer: {
clientLogLevel: 'warning',
historyApiFallback: {
rewrites: [
{ from: /.*/, to: path.posix.join(config.dev.assetsPublicPath, 'index.html') },
],
},
hot: true,
contentBase: false, // since we use CopyWebpackPlugin.
compress: true,
host: HOST || config.dev.host,
port: PORT || config.dev.port,
open: config.dev.autoOpenBrowser,
overlay: config.dev.errorOverlay
? { warnings: false, errors: true }
: false,
publicPath: config.dev.assetsPublicPath,
proxy: config.dev.proxyTable,
quiet: true, // necessary for FriendlyErrorsPlugin
watchOptions: {
poll: config.dev.poll,
}
},
plugins: [
new webpack.DefinePlugin({
'process.env': require('../config/dev.env')
}),
new webpack.HotModuleReplacementPlugin(),
new webpack.NamedModulesPlugin(), // HMR shows correct file names in console on update.
new webpack.NoEmitOnErrorsPlugin(),
// https://github.com/ampedandwired/html-webpack-plugin
new HtmlWebpackPlugin({
filename: 'index.html',
template: 'index.html',
inject: true
}),
// copy custom static assets
new CopyWebpackPlugin([
{
from: path.resolve(__dirname, '../static'),
to: config.dev.assetsSubDirectory,
ignore: ['.*']
}
])
]
})
module.exports = new Promise((resolve, reject) => {
portfinder.basePort = process.env.PORT || config.dev.port
portfinder.getPort((err, port) => {
if (err) {
reject(err)
} else {
// publish the new Port, necessary for e2e tests
process.env.PORT = port
// add port to devServer config
devWebpackConfig.devServer.port = port
// Add FriendlyErrorsPlugin
devWebpackConfig.plugins.push(new FriendlyErrorsPlugin({
compilationSuccessInfo: {
messages: [`Your application is running here: http://${devWebpackConfig.devServer.host}:${port}`],
},
onErrors: config.dev.notifyOnErrors
? utils.createNotifierCallback()
: undefined
}))
resolve(devWebpackConfig)
}
})
})
build/webpack.prod.conf.js
const path = require('path')
const utils = require('./utils')
const webpack = require('webpack')
const config = require('../config')
const merge = require('webpack-merge')
const baseWebpackConfig = require('./webpack.base.conf')
const CopyWebpackPlugin = require('copy-webpack-plugin')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const ExtractTextPlugin = require('extract-text-webpack-plugin')
const OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin')
const UglifyJsPlugin = require('uglifyjs-webpack-plugin')
const env = require('../config/prod.env')
const webpackConfig = merge(baseWebpackConfig, {
module: {
rules: utils.styleLoaders({
sourceMap: config.build.productionSourceMap,
extract: true,
usePostCSS: true
})
},
devtool: config.build.productionSourceMap ? config.build.devtool : false,
output: {
path: config.build.assetsRoot,
filename: utils.assetsPath('js/[name].[chunkhash].js'),
chunkFilename: utils.assetsPath('js/[id].[chunkhash].js')
},
plugins: [
// http://vuejs.github.io/vue-loader/en/workflow/production.html
new webpack.DefinePlugin({
'process.env': env
}),
new UglifyJsPlugin({
uglifyOptions: {
compress: {
warnings: false
}
},
sourceMap: config.build.productionSourceMap,
parallel: true
}),
// extract css into its own file
new ExtractTextPlugin({
filename: utils.assetsPath('css/[name].[contenthash].css'),
// Setting the following option to `false` will not extract CSS from codesplit chunks.
// Their CSS will instead be inserted dynamically with style-loader when the codesplit chunk has been loaded by webpack.
// It's currently set to `true` because we are seeing that sourcemaps are included in the codesplit bundle as well when it's `false`,
// increasing file size: https://github.com/vuejs-templates/webpack/issues/1110
allChunks: true,
}),
// Compress extracted CSS. We are using this plugin so that possible
// duplicated CSS from different components can be deduped.
new OptimizeCSSPlugin({
cssProcessorOptions: config.build.productionSourceMap
? { safe: true, map: { inline: false } }
: { safe: true }
}),
// generate dist index.html with correct asset hash for caching.
// you can customize output by editing /index.html
// see https://github.com/ampedandwired/html-webpack-plugin
new HtmlWebpackPlugin({
filename: config.build.index,
template: 'index.html',
inject: true,
minify: {
removeComments: true,
collapseWhitespace: true,
removeAttributeQuotes: true
// more options:
// https://github.com/kangax/html-minifier#options-quick-reference
},
// necessary to consistently work with multiple chunks via CommonsChunkPlugin
chunksSortMode: 'dependency'
}),
// keep module.id stable when vendor modules does not change
new webpack.HashedModuleIdsPlugin(),
// enable scope hoisting
new webpack.optimize.ModuleConcatenationPlugin(),
// split vendor js into its own file
new webpack.optimize.CommonsChunkPlugin({
name: 'vendor',
minChunks (module) {
// any required modules inside node_modules are extracted to vendor
return (
module.resource &&
/\.js$/.test(module.resource) &&
module.resource.indexOf(
path.join(__dirname, '../node_modules')
) === 0
)
}
}),
// extract webpack runtime and module manifest to its own file in order to
// prevent vendor hash from being updated whenever app bundle is updated
new webpack.optimize.CommonsChunkPlugin({
name: 'manifest',
minChunks: Infinity
}),
// This instance extracts shared chunks from code splitted chunks and bundles them
// in a separate chunk, similar to the vendor chunk
// see: https://webpack.js.org/plugins/commons-chunk-plugin/#extra-async-commons-chunk
new webpack.optimize.CommonsChunkPlugin({
name: 'app',
async: 'vendor-async',
children: true,
minChunks: 3
}),
// copy custom static assets
new CopyWebpackPlugin([
{
from: path.resolve(__dirname, '../static'),
to: config.build.assetsSubDirectory,
ignore: ['.*']
}
])
]
})
if (config.build.productionGzip) {
const CompressionWebpackPlugin = require('compression-webpack-plugin')
webpackConfig.plugins.push(
new CompressionWebpackPlugin({
asset: '[path].gz[query]',
algorithm: 'gzip',
test: new RegExp(
'\\.(' +
config.build.productionGzipExtensions.join('|') +
')$'
),
threshold: 10240,
minRatio: 0.8
})
)
}
if (config.build.bundleAnalyzerReport) {
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
webpackConfig.plugins.push(new BundleAnalyzerPlugin())
}
module.exports = webpackConfig
I'll gladly provide any other files if they're helpful.
Here's how I import pdfjs-dist:
text.js
var pdfjs = require('pdfjs-dist');
pdfjs.disableWorker = true
My guess on the problem is that pdfjs requires the workerSrc property to be known in runtime. But when you use webpack it will probably assign an unguessable hash on the file name, so you can't really put the filename as a string in your code.
But pdfjs provides a solution for us! They have included a webpack file in their distribution.
In your code
var pdfjs = require("pdfjs-dist/webpack");
//we dont't include the normal module
//but the one with the webpack configuration
//that the pdfjs team provides us.
//no need to disable worker
//or point to the workerSrc
So what this thing does
//inside "pdfjs-dist/webpack"
'use strict';
var pdfjs = require('./build/pdf.js');
var PdfjsWorker = require('worker-loader!./build/pdf.worker.js');
if (typeof window !== 'undefined' && 'Worker' in window) {
pdfjs.GlobalWorkerOptions.workerPort = new PdfjsWorker();
}
module.exports = pdfjs;
Basically it includes the original build from ./build/pdf.js and it will also import for us the worker script with the worker-loader. A webpack loader designed to import web-workers in our apps. Then it assigns the actual worker in the pdfjs instance and it exports it.
After you import the above file in your app you will have a pdfjs instance configured with a web-worker ready for your bundle!

Resources