feat: 动态载入node-serialport和node-usb避免nwjs下server异常
This commit is contained in:
3
.gitignore
vendored
3
.gitignore
vendored
@@ -8,4 +8,5 @@ yarn.lock
|
||||
dist
|
||||
/temp
|
||||
/arduino-cli
|
||||
/certs
|
||||
/bundle.cjs
|
||||
/nw_cache
|
||||
|
||||
26
cert/server.crt
Normal file
26
cert/server.crt
Normal file
@@ -0,0 +1,26 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIEXjCCAsagAwIBAgIQawifoA3zcQJDuoDTSaOE7DANBgkqhkiG9w0BAQsFADCB
|
||||
hTEeMBwGA1UEChMVbWtjZXJ0IGRldmVsb3BtZW50IENBMS0wKwYDVQQLDCRERVNL
|
||||
VE9QLVZQMU4zNzJcVXNlckBERVNLVE9QLVZQMU4zNzIxNDAyBgNVBAMMK21rY2Vy
|
||||
dCBERVNLVE9QLVZQMU4zNzJcVXNlckBERVNLVE9QLVZQMU4zNzIwHhcNMjUwNTIy
|
||||
MTAzNDM4WhcNMjcwODIyMTAzNDM4WjBYMScwJQYDVQQKEx5ta2NlcnQgZGV2ZWxv
|
||||
cG1lbnQgY2VydGlmaWNhdGUxLTArBgNVBAsMJERFU0tUT1AtVlAxTjM3MlxVc2Vy
|
||||
QERFU0tUT1AtVlAxTjM3MjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
|
||||
APJR4a5Xjf7MTkUocnqH2HqvhArI7hV7XZDbKPBJSlcyQUGKFRBXA7vrHg7YlVCZ
|
||||
4vKHieUKNNNaPLUUVRGzjV2W6JFCmtYyoLBSijIxjEcT9iNHT8ndF3vx+ExfQmRB
|
||||
qYvmGWCvnZ5NpF807ZIbabSmF7ZLrl6atp437SZ3a+xTCsGIkJf9JQvIfj5Un9tR
|
||||
ed6h/P0mOJGlxzq28yljUTpgolU2iCLnE4zlnNttkm1o+X0CnhtqK2oO0h0x7Nlz
|
||||
UkMvl4Y0CiUZpqG0r3Fy8JRrM7ZXf4EXTzT2uTQVI9+Hh4T+lBqCJ4QZXqJWrQ3a
|
||||
EqQ1+3NWRfWe/41Oq+rkKSkCAwEAAaN2MHQwDgYDVR0PAQH/BAQDAgWgMBMGA1Ud
|
||||
JQQMMAoGCCsGAQUFBwMBMB8GA1UdIwQYMBaAFIb2OJENGB0jIgBAczrFu8nddW/m
|
||||
MCwGA1UdEQQlMCOCCWxvY2FsaG9zdIcErBhRrIcEqf4ojYcEwKjMAYcEfwAAATAN
|
||||
BgkqhkiG9w0BAQsFAAOCAYEAe+oeVFZfEtz7dOSpqELA937hN4buhIGgB+gLZV1O
|
||||
3HR5fh22lVl3CldcxdGoGWcpWurrd37DVBtM04OHOzS1R6cMeXlksRe6hPBRT0F2
|
||||
D/9dtr2n8vIEEjRv2C6heuU8uSHHzgsD5PSSRdbCJ5UkoEMqVhbH2G5y7SBLc3uY
|
||||
GnTb+BLA2+CP5IJIScXi0CGh/NN+fLEm8zYmxfeR5aP8O40DS0NobyM+wiv0UUsw
|
||||
d0CK6GS/0iOFB05f/pGINiFRsgN5l1O0FXnWCt043XO10yqOG2yw6rB1NsvzsAuG
|
||||
D2wl8BcAres9qT87Ac80h1lXDJ0gZIJxNUSJBPJxJ9c8U9NVrXMXMMBkYrXFbdQH
|
||||
J7cQ8/yQjkz4aqHEtt1Z+9bdx/1WEKsgoXtyZEYiGE97rD9kZ+7qJHFkDAKI3wS2
|
||||
eD14gFISoPt/X3eV+rbfrdcyUrIqesTXT7wF/L8+6XIrhRXXlq4S1zGZOf4HryH2
|
||||
QLD0nwTcDhtpz7m7wKANkXga
|
||||
-----END CERTIFICATE-----
|
||||
28
cert/server.key
Normal file
28
cert/server.key
Normal file
@@ -0,0 +1,28 @@
|
||||
-----BEGIN PRIVATE KEY-----
|
||||
MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQDyUeGuV43+zE5F
|
||||
KHJ6h9h6r4QKyO4Ve12Q2yjwSUpXMkFBihUQVwO76x4O2JVQmeLyh4nlCjTTWjy1
|
||||
FFURs41dluiRQprWMqCwUooyMYxHE/YjR0/J3Rd78fhMX0JkQamL5hlgr52eTaRf
|
||||
NO2SG2m0phe2S65emraeN+0md2vsUwrBiJCX/SULyH4+VJ/bUXneofz9JjiRpcc6
|
||||
tvMpY1E6YKJVNogi5xOM5ZzbbZJtaPl9Ap4baitqDtIdMezZc1JDL5eGNAolGaah
|
||||
tK9xcvCUazO2V3+BF0809rk0FSPfh4eE/pQagieEGV6iVq0N2hKkNftzVkX1nv+N
|
||||
Tqvq5CkpAgMBAAECggEBALgdVM9FwSL/Et1jLRBClU4qe7ZCEvwJfv8oNgPUfAKi
|
||||
sYhdpUGEC9dFftIi59iVBCXoq/J1/cs0vfmMGFLZzSh2GAD+zWzAjO1L2arnkMEU
|
||||
vqjxbwNe1JAdOt60ZlqMtYkRbOjUpnr4XVLlgTjJUVir9kpRWIyTGvw+XBclF8A3
|
||||
oe856SzNp7sErkNDULrv8EYAjiynlg1NB1s4Ek5t9pxlQcx8G6qRWjVhdvNAarRy
|
||||
32mmWRkTt58e/I4ZPHHWG9NUHVRqeNK45Ak4dw0dth4j/BShhq+VWCoQmLESHtu7
|
||||
PU30u+57tC2DuvXUsmWFqGwVkU4g942QHYQicMeCLw0CgYEA+pWBdxtSH2ItwwLv
|
||||
IyNLCQjzz4Wq/0X8l5K+w98vb53buzSEHWoC/JQkChkAxYppe1dUQwLLX07FgYTp
|
||||
dAhFuHuJkSil8i6kwLoArNzdybUgQORKps2oi820ANRzFljBBqkcCGGYpbzGu3fd
|
||||
eEhiUeGALyzzIwt7wtGxfu7aumsCgYEA946mW5pMBcRbQhfT1dfhiCj6HZW47wXh
|
||||
b7u20tCQOFGpHEcLcwWHaFNUBTTbvrqXYFjI3VKY4adXdvj6Qgc71Tv0mQRiUjxg
|
||||
dAeV5wwEKCSRelNtbNcsXMe6oxn7jzNdtRn/zzP3OZ9Yo8O4cgQSBthYBx8NLI55
|
||||
Uv4RWV9zN7sCgYA/mtFY5UNsGeSZulXu6ldyfKY+R6SG1UHvS11GpJEK2NvcYdEj
|
||||
EjSd3hBjy8LpYV+y4hDOTZhHodv6Kz2CqVLhJ+JcSSAOIA7LqKrhNdLKD0KXlhro
|
||||
ygz9J4KIL2TjCDY+tZAbBILVltwu25cIn/7s37tEvjkc7R5F7ioKmSBF7wKBgQDe
|
||||
nnp9j9DjssN6OSE3ga6AGpFpv3WSBRDIwN7Uz9eRveW81yq1ofg12hGJqRIff36X
|
||||
lt/zH875xdnC1H2AmS62P/djD203lLIMRbIJF2Y5j0D/5zxVD18GhFoTSE9PZJrV
|
||||
PG8trwaY2/IDOwOIDJ8FZtIqfUMEmY8DEhUZ8NsU9wKBgQCwfDybwBJMQ6uueNW6
|
||||
MfMlYaiQkoc5G5JjJgLRdXspsVUTsVtKmW3OWMxYjHoX2il1o+SvhNyl6pT6ydK4
|
||||
X674hLtkCYiXHQvBimNTu5S0/8N/SG5k0NDKEDYHdMLT/s/mMzNofte1Tr8wGXzy
|
||||
choMXR4QUuGbI/CPicSC+bD9Fg==
|
||||
-----END PRIVATE KEY-----
|
||||
@@ -23,14 +23,15 @@
|
||||
},
|
||||
"client": {
|
||||
"path": "./mixly",
|
||||
"port": 4000
|
||||
"port": 7000,
|
||||
"protocol": "https:"
|
||||
},
|
||||
"server": {
|
||||
"path": {
|
||||
"temp": "./temp"
|
||||
},
|
||||
"mode": "all",
|
||||
"protocol": "wss",
|
||||
"port": 4000
|
||||
"protocol": "wss:",
|
||||
"port": 7000
|
||||
}
|
||||
}
|
||||
37
config.json.nw
Normal file
37
config.json.nw
Normal file
@@ -0,0 +1,37 @@
|
||||
{
|
||||
"debug": true,
|
||||
"arduino": {
|
||||
"path": {
|
||||
"folder": "./arduino-cli",
|
||||
"cli": "./arduino-cli/arduino-cli.exe",
|
||||
"libraries": [
|
||||
"./arduino-libs/arduino-cli/libraries"
|
||||
],
|
||||
"config": "./arduino-cli/arduino-cli.json"
|
||||
}
|
||||
},
|
||||
"micropython": {
|
||||
"path": {
|
||||
"ampy": "./mixly/tools/python/ampy_main.py",
|
||||
"esptool": "./mixly/tools/python/esptool_main.py"
|
||||
}
|
||||
},
|
||||
"python": {
|
||||
"path": {
|
||||
"cli": "python3"
|
||||
}
|
||||
},
|
||||
"client": {
|
||||
"path": "./mixly",
|
||||
"port": 7000,
|
||||
"protocol": "http:"
|
||||
},
|
||||
"server": {
|
||||
"path": {
|
||||
"temp": "./temp"
|
||||
},
|
||||
"mode": "compiler",
|
||||
"protocol": "ws:",
|
||||
"port": 7000
|
||||
}
|
||||
}
|
||||
2
mixly
2
mixly
Submodule mixly updated: 13463ce183...c3e7039ffa
@@ -3,7 +3,7 @@
|
||||
"type": "module",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "src/index.js",
|
||||
"main": "./src/index.js",
|
||||
"scripts": {
|
||||
"cert:generate": "node ./scripts/cert-generate.js",
|
||||
"arduino:install": "node ./scripts/arduino-install.js",
|
||||
|
||||
72
package.json.nw
Normal file
72
package.json.nw
Normal file
@@ -0,0 +1,72 @@
|
||||
{
|
||||
"name": "mixly3-server",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"node-main": "./bundle.cjs",
|
||||
"main": "http://127.0.0.1:7000/mixly",
|
||||
"node-remote": "http://127.0.0.1:7000/mixly",
|
||||
"scripts": {
|
||||
"start": "nw ./ --remote-debugging-port=9222",
|
||||
"build:prod": "webpack --config=webpack.nw.cjs",
|
||||
"build:nw:win:x64": "npm run build:prod && build --tasks win-x64 --mirror https://npmmirror.com/mirrors/nwjs/ .",
|
||||
"build:nw:win:x86": "npm run build:prod && build --tasks win-x86 --mirror https://npmmirror.com/mirrors/nwjs/ .",
|
||||
"build:nw:linux:x64": "npm run build:prod && build --tasks linux-x64 --mirror https://npmmirror.com/mirrors/nwjs/ .",
|
||||
"build:nw:mac:x64": "npm run build:prod && build --tasks mac-x64 --mirror https://npmmirror.com/mirrors/nwjs/ ."
|
||||
},
|
||||
"window": {
|
||||
"icon": "mixly/common/media/mixly.png",
|
||||
"position": "center"
|
||||
},
|
||||
"keywords": [
|
||||
"NW.js",
|
||||
"server"
|
||||
],
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://gitee.com/bnu_mixly/mixly3-server.git"
|
||||
},
|
||||
"author": "Mixly Team",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"await-to-js": "^3.0.0",
|
||||
"better-sse": "^0.14.1",
|
||||
"commander": "^12.1.0",
|
||||
"decompress": "^4.2.1",
|
||||
"decompress-unzip": "^4.0.1",
|
||||
"express": "^4.21.1",
|
||||
"fs": "^0.0.1-security",
|
||||
"fs-extra": "^11.2.0",
|
||||
"fs-plus": "^3.1.1",
|
||||
"http": "^0.0.1-security",
|
||||
"iconv-lite": "^0.6.3",
|
||||
"lodash": "^4.17.21",
|
||||
"mitt": "^3.0.1",
|
||||
"mustache": "^4.2.0",
|
||||
"node-fetch": "^3.3.2",
|
||||
"node-forge": "^1.3.1",
|
||||
"path": "^0.12.7",
|
||||
"serialport": "^12.0.0",
|
||||
"shelljs": "^0.9.2",
|
||||
"shortid": "^2.2.17",
|
||||
"simple-git": "^3.27.0",
|
||||
"socket.io": "^4.8.1",
|
||||
"tar": "^7.4.3",
|
||||
"url": "^0.11.0",
|
||||
"usb": "^2.14.0"
|
||||
},
|
||||
"build": {
|
||||
"nwVersion": "0.72.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"eslint": "^8.57.1",
|
||||
"eslint-webpack-plugin": "^4.0.1",
|
||||
"nodemon": "^3.1.10",
|
||||
"npm-run-all": "^4.1.5",
|
||||
"nw": "0.72.0-sdk",
|
||||
"nwjs-builder-phoenix": "^1.15.0",
|
||||
"webpack": "^5.89.0",
|
||||
"webpack-cli": "^5.1.4",
|
||||
"webpack-merge": "^6.0.1",
|
||||
"webpack-node-externals": "^3.0.0"
|
||||
}
|
||||
}
|
||||
@@ -29,9 +29,10 @@ export const MICROPYTHON = processConfig(CONFIG.micropython);
|
||||
export const PYTHON = processConfig(CONFIG.python);
|
||||
export const CURRENT_PLANTFORM = os.platform();
|
||||
export const TEMP_PATH = path.resolve(process.cwd(), CONFIG.server.path.temp);
|
||||
export const CLIENT_PATH = path.resolve(process.cwd(), CONFIG.client.path);
|
||||
export const CERTS_PATH = path.resolve(process.cwd(), 'certs');
|
||||
export const CLIENT_PORT = CONFIG.client.port;
|
||||
export const CLIENT_PATH = path.resolve(process.cwd(), CONFIG.client.path);
|
||||
export const CLIENT_PROTOCOL = CONFIG.client.protocol;
|
||||
export const SERVER_PORT = CONFIG.server.protocol === 'wss' ? CLIENT_PORT : CONFIG.server.port;
|
||||
export const SERVER_MODE = CONFIG.server.mode;
|
||||
export const SERVER_PROTOCOL = CONFIG.server.protocol;
|
||||
@@ -1,12 +1,17 @@
|
||||
import { exec } from 'node:child_process';
|
||||
import {
|
||||
SerialPort,
|
||||
ReadlineParser,
|
||||
ByteLengthParser
|
||||
} from 'serialport';
|
||||
import _ from 'lodash';
|
||||
import EventsBase from './events-base.js';
|
||||
import { CURRENT_PLANTFORM } from './config.js';
|
||||
import { CURRENT_PLANTFORM, SERVER_MODE } from './config.js';
|
||||
|
||||
|
||||
let SerialPort, ReadlineParser, ByteLengthParser;
|
||||
|
||||
if (SERVER_MODE === 'all') {
|
||||
const serial = await import('serialport');
|
||||
SerialPort = serial.SerialPort;
|
||||
ReadlineParser = serial.ReadlineParser;
|
||||
ByteLengthParser = serial.ByteLengthParser;
|
||||
}
|
||||
|
||||
|
||||
export default class Serial extends EventsBase {
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { Server } from 'socket.io';
|
||||
import { to } from 'await-to-js';
|
||||
import { usb } from 'usb';
|
||||
import path from 'node:path';
|
||||
import fsExtra from 'fs-extra';
|
||||
import Serial from './serial.js';
|
||||
@@ -11,7 +10,7 @@ import ShellMicroPython from './shell-micropython.js';
|
||||
import ShellAmpy from './shell-ampy.js';
|
||||
import MString from './mstring.js';
|
||||
import Boards from './boards.js';
|
||||
import { TEMP_PATH, CLIENT_PATH } from './config.js';
|
||||
import { TEMP_PATH, CLIENT_PATH, SERVER_MODE } from './config.js';
|
||||
|
||||
|
||||
export default class Socket {
|
||||
@@ -37,12 +36,16 @@ export default class Socket {
|
||||
this.#shellAmpy_.register(socket.id, new ShellAmpy());
|
||||
this.#addEventsListenerForMode2_(socket);
|
||||
});
|
||||
usb.on('attach', (device) => {
|
||||
this.#namespaceAll_.emit('serial.attachEvent', device);
|
||||
});
|
||||
usb.on('detach', (device) => {
|
||||
this.#namespaceAll_.emit('serial.detachEvent', device);
|
||||
});
|
||||
if (SERVER_MODE === 'all') {
|
||||
import('usb').then(({ usb }) => {
|
||||
usb.on('attach', (device) => {
|
||||
this.#namespaceAll_.emit('serial.attachEvent', device);
|
||||
});
|
||||
usb.on('detach', (device) => {
|
||||
this.#namespaceAll_.emit('serial.detachEvent', device);
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
#addEventsListenerForMode1_(socket) {
|
||||
|
||||
@@ -2,9 +2,9 @@ import os from 'node:os';
|
||||
import path from 'node:path';
|
||||
import fsExtra from 'fs-extra';
|
||||
import fsPlus from 'fs-plus';
|
||||
import forge from 'node-forge';
|
||||
// import forge from 'node-forge';
|
||||
import shell from 'shelljs';
|
||||
import _ from 'lodash';
|
||||
// import _ from 'lodash';
|
||||
import { CERTS_PATH } from './config.js';
|
||||
|
||||
|
||||
@@ -50,7 +50,7 @@ export function getCertificate() {
|
||||
data.cert = fsExtra.readFileSync(crtPath);
|
||||
data.key = fsExtra.readFileSync(keyPath);
|
||||
}
|
||||
const cert = forge.pki.certificateFromPem(data.cert);
|
||||
/* const cert = forge.pki.certificateFromPem(data.cert);
|
||||
const now = new Date();
|
||||
const notBefore = cert.validity.notBefore;
|
||||
const notAfter = cert.validity.notAfter;
|
||||
@@ -73,6 +73,6 @@ export function getCertificate() {
|
||||
}
|
||||
} else {
|
||||
data = generateCertificate();
|
||||
}
|
||||
} */
|
||||
return data;
|
||||
}
|
||||
54
src/index.js
54
src/index.js
@@ -5,21 +5,43 @@ import fsExtra from 'fs-extra';
|
||||
import express from 'express';
|
||||
import Socket from './common/socket.js';
|
||||
import { getCertificate } from './common/utils.js';
|
||||
import { CLIENT_PATH, CLIENT_PORT, SERVER_PORT, SERVER_MODE, SERVER_PROTOCOL } from './common/config.js';
|
||||
import {
|
||||
CLIENT_PATH, CLIENT_PORT, CLIENT_PROTOCOL,
|
||||
SERVER_MODE, SERVER_PORT, SERVER_PROTOCOL
|
||||
} from './common/config.js';
|
||||
|
||||
|
||||
process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0';
|
||||
const app = express();
|
||||
|
||||
if (CLIENT_PATH) {
|
||||
app.use(express.static(CLIENT_PATH));
|
||||
if (typeof nw === 'object') {
|
||||
app.use(express.static(path.resolve(CLIENT_PATH, '../')));
|
||||
} else {
|
||||
app.use(express.static(CLIENT_PATH));
|
||||
}
|
||||
}
|
||||
const httpsServer = https.createServer(getCertificate(), app);
|
||||
let httpServer = null;
|
||||
if (CLIENT_PORT !== SERVER_PORT) {
|
||||
httpServer = http.createServer()
|
||||
|
||||
let staticServer = null;
|
||||
let socketServer = null;
|
||||
|
||||
if (CLIENT_PROTOCOL === 'https:') {
|
||||
staticServer = https.createServer(getCertificate(), app);
|
||||
} else {
|
||||
staticServer = http.createServer(app);
|
||||
}
|
||||
|
||||
if (SERVER_MODE !== 'static') {
|
||||
const socket = new Socket(httpServer ? httpServer : httpsServer, {
|
||||
if (CLIENT_PORT === SERVER_PORT) {
|
||||
socketServer = staticServer;
|
||||
} else {
|
||||
if (SERVER_PROTOCOL === 'wss:') {
|
||||
socketServer = https.createServer(getCertificate());
|
||||
} else {
|
||||
socketServer = http.createServer();
|
||||
}
|
||||
}
|
||||
const socket = new Socket(socketServer, {
|
||||
path: '/mixly-socket/',
|
||||
maxHttpBufferSize: 1e8,
|
||||
cors: {
|
||||
@@ -52,11 +74,11 @@ const mixlyConfig = fsExtra.readJSONSync(mixlyConfigPath);
|
||||
|
||||
if (SERVER_MODE === 'compiler') {
|
||||
mixlyConfig['webCompiler']['enabled'] = true;
|
||||
mixlyConfig['webCompiler']['url'] = `${SERVER_PROTOCOL}://default:${SERVER_PORT}`;
|
||||
mixlyConfig['webCompiler']['url'] = `${SERVER_PROTOCOL}//default:${SERVER_PORT}`;
|
||||
mixlyConfig['webSocket']['enabled'] = false;
|
||||
} else if (SERVER_MODE === 'all') {
|
||||
mixlyConfig['webCompiler']['enabled'] = false;
|
||||
mixlyConfig['webSocket']['url'] = `${SERVER_PROTOCOL}://default:${SERVER_PORT}`;
|
||||
mixlyConfig['webSocket']['url'] = `${SERVER_PROTOCOL}//default:${SERVER_PORT}`;
|
||||
mixlyConfig['webSocket']['enabled'] = true;
|
||||
} else {
|
||||
mixlyConfig['webCompiler']['enabled'] = false;
|
||||
@@ -67,13 +89,17 @@ fsExtra.writeJSONSync(mixlyConfigPath, mixlyConfig, {
|
||||
spaces: ' '
|
||||
});
|
||||
|
||||
httpsServer.listen(CLIENT_PORT);
|
||||
if (httpServer) {
|
||||
httpServer.listen(SERVER_PORT);
|
||||
if (CLIENT_PORT === SERVER_PORT) {
|
||||
staticServer?.listen(CLIENT_PORT);
|
||||
} else {
|
||||
staticServer?.listen(CLIENT_PORT);
|
||||
socketServer?.listen(SERVER_PORT);
|
||||
}
|
||||
|
||||
if (CLIENT_PATH) {
|
||||
console.log(`Static服务器正在运行: https://127.0.0.1:${CLIENT_PORT}`);
|
||||
console.log(`Static服务器正在运行: ${CLIENT_PROTOCOL}//127.0.0.1:${CLIENT_PORT}`);
|
||||
}
|
||||
|
||||
if (SERVER_MODE !== 'static') {
|
||||
console.log(`Socket.io服务器正在运行: ${SERVER_PROTOCOL}://127.0.0.1:${SERVER_PORT}`);
|
||||
console.log(`Socket.io服务器正在运行: ${SERVER_PROTOCOL}//127.0.0.1:${SERVER_PORT}`);
|
||||
}
|
||||
@@ -9,5 +9,5 @@ module.exports = {
|
||||
path: path.resolve(__dirname, 'dist'),
|
||||
filename: 'bundle.cjs'
|
||||
},
|
||||
externals: [nodeExternals()],
|
||||
externals: [nodeExternals()]
|
||||
};
|
||||
11
webpack.nw.cjs
Normal file
11
webpack.nw.cjs
Normal file
@@ -0,0 +1,11 @@
|
||||
const common = require('./webpack.common.cjs');
|
||||
const { merge } = require('webpack-merge');
|
||||
|
||||
|
||||
module.exports = merge(common, {
|
||||
output: {
|
||||
path: __dirname,
|
||||
filename: 'bundle.cjs'
|
||||
},
|
||||
mode: 'production'
|
||||
});
|
||||
Reference in New Issue
Block a user