parcel-bundler / parcel

The zero configuration build tool for the web. πŸ“¦πŸš€

Home Page:https://parceljs.org

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

This experimental syntax requires enabling the parser plugin: 'optionalChaining'

liudonghua123 opened this issue Β· comments

πŸ› bug report

πŸŽ› Configuration (.babelrc, package.json, cli command)

{
  "name": "web-terminal-turorial-client",
  "version": "1.0.0",
  "description": "",
  "main": "index.html",
  "scripts": {
    "start": "parcel index.html --open",
    "build": "parcel build --public-url ./ index.html"
  },
  "dependencies": {
    "socket.io-client": "^4.7.5",
    "xterm": "^5.4.0"
  },
  "devDependencies": {
    "@babel/core": "7.2.0",
    "parcel-bundler": "^1.6.1"
  },
  "keywords": []
}
parcel build --public-url ./ index.html

πŸ€” Expected Behavior

It should be ok when I update xterm from "4.2.0"/"5.3.0" to "^5.4.0"

😯 Current Behavior

yarn build failed with the following errors.

 > yarn build
yarn run v1.22.17
warning package.json: No license field
$ parcel build --public-url ./ index.html
\ Building index.js...Browserslist: caniuse-lite is outdated. Please run next command `yarn upgrade`
- Building backo2.js...Browserslist: caniuse-lite is outdated. Please run next command `yarn upgrade`
Browserslist: caniuse-lite is outdated. Please run next command `yarn upgrade`
Γ—  D:\code\node\how-to-create-web-terminals\client\node_modules\xterm\lib\xterm.js:1:11295: This experimental syntax requires enabling the parser plugin: 'optionalChaining' (1:11295)
> 1 | !function(e,t){if("object"==typeof exports&&"object"==typeof module)module.exports=t();else if("function"==typeof 
......

πŸ’ Possible Solution

πŸ”¦ Context

πŸ’» Code Sample

index.html

<!DOCTYPE html>
<html>
  <head>
    <title>How to create web terminals</title>
    <meta charset="UTF-8" />
  </head>

  <body>
    <div id="terminal-container"></div>
    <script src="src/index.js"></script>
  </body>
</html>

index.js

// index.js

import { TerminalUI } from "./TerminalUI.js";
import io from "socket.io-client";

// IMPORTANT: Make sure you replace this address with your server address.

const serverAddress = "http://localhost:8080";

//Server sandbox available at https://codesandbox.io/s/web-terminal-tutorial-server-g2ihu

function connectToSocket(serverAddress) {
  return new Promise(res => {
    const socket = io(serverAddress);
    res(socket);
  });
}

function startTerminal(container, socket) {
  // Create an xterm.js instance (TerminalUI class is a wrapper with some utils. Check that file for info.)
  const terminal = new TerminalUI(socket);

  // Attach created terminal to a DOM element.
  terminal.attachTo(container);

  // When terminal attached to DOM, start listening for input, output events.
  // Check TerminalUI startListening() function for details.
  terminal.startListening();
}

function start() {
  const container = document.getElementById("terminal-container");
  // Connect to socket and when it is available, start terminal.
  connectToSocket(serverAddress).then(socket => {
    startTerminal(container, socket);
  });
}

// Better to start on DOMContentLoaded. So, we know terminal-container is loaded
start();

TerminalUI.js

// TerminalUI.js

import { Terminal } from "xterm";

// import the xterm.css if use bundlers or insert link element in the head
// <link rel="stylesheet" href="https://unpkg.com/xterm@5.4.0-release/css/xterm.css" />
import "xterm/css/xterm.css";

export class TerminalUI {
  constructor(socket) {
    this.terminal = new Terminal();

    /* You can make your terminals colorful :) */
    // https://github.com/xtermjs/xterm.js/issues/4256#issuecomment-1510977408
    // this.terminal.setOption("theme", {
    //   background: "#202B33",
    //   foreground: "#F5F8FA"
    // });
    this.terminal.options.theme = {
      background: "#202B33",
      foreground: "#F5F8FA"
    };

    this.socket = socket;
  }

  /**
   * Attach event listeners for terminal UI and socket.io client
   */
  startListening() {
    this.terminal.onData(data => this.sendInput(data));
    this.socket.on("output", data => {
      // When there is data from PTY on server, print that on Terminal.
      this.write(data);
    });
  }

  /**
   * Print something to terminal UI.
   */
  write(text) {
    this.terminal.write(text);
  }

  /**
   * Utility function to print new line on terminal.
   */
  prompt() {
    this.terminal.write(`\r\n$ `);
  }

  /**
   * Send whatever you type in Terminal UI to PTY process in server.
   * @param {*} input Input to send to server
   */
  sendInput(input) {
    this.socket.emit("input", input);
  }

  /**
   *
   * @param {HTMLElement} container HTMLElement where xterm can attach terminal ui instance.
   */
  attachTo(container) {
    this.terminal.open(container);
    // Default text to display on terminal.
    this.terminal.write("Terminal Connected");
    this.terminal.write("");
    this.prompt();
  }

  clear() {
    this.terminal.clear();
  }
}

🌍 Your Environment

Software Version(s)
Parcel ^1.6.1
Node v20.11.1
npm/Yarn 10.5.0/1.22.17
Operating System Microsoft Windows [Version 10.0.22631.3374]

Parcel 1 isn't supported anymore.
Otherwise, bumping Babel-related packages in your lockfile might help.

Parcel 1 isn't supported anymore.
Otherwise, bumping Babel-related packages in your lockfile might help.

Thanks, I found the official migration guide https://parceljs.org/getting-started/migration/, i will try to update parcel 2 later.