Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[question] Integrating terminal-kit with webpack project #176

Closed
dustyhorizon opened this issue May 23, 2021 · 15 comments
Closed

[question] Integrating terminal-kit with webpack project #176

dustyhorizon opened this issue May 23, 2021 · 15 comments

Comments

@dustyhorizon
Copy link

Hello,

I am currently exploring the integration of terminal-kit in a vue/webpack based project alongside xterm.js and commander.js for a pseudo webtty interface. However, webpack doesn't seem to play well with the lazy loading for this library.

Specifically, the vue/webpack dev server loads with an error Critical dependency: require function is used in a way in which dependencies cannot be statically extracted and throws Cannot find module chroma-js in the browser's console.

I have tried adding chroma-js as an external dependency in webpack config but to no avail, any advice?

cronvel added a commit that referenced this issue May 24, 2021
@cronvel
Copy link
Owner

cronvel commented May 24, 2021

@dustyhorizon Hi, on v2.1.3, try loading a new entry point: require('terminal-kit/lib/termkit-no-lazy-require.js').

@dustyhorizon
Copy link
Author

@cronvel Thanks for the new feature but seems like its not working with the webpack polyfill for browser targets and xterm.js.

Was hoping that I could use terminal-kit for local-echo in xterm.js in browser.

@cronvel
Copy link
Owner

cronvel commented May 24, 2021

@dustyhorizon Can you explain a bit what is happening? Which polyfill breaks things?

@dustyhorizon
Copy link
Author

dustyhorizon commented May 24, 2021

@dustyhorizon Can you explain a bit what is happening? Which polyfill breaks things?

With a simple vue-cli init-ed project and xterm.js initialized, I did a simple shim for stdin/stdout/stderr via

terminal.isTTY = true;
    process.stdout =
      process.stderr =
      process.stdin =
        {
          isTTY: true,
          write: (data: string) => {
            terminal.write(data.replace(/\n/g, "\r\n"));
          },
        } as any;

With your new entry point I am having new errors like the following:

 ERROR  Failed to compile with 2 errors                                                                                             10:47:12 PM

 error  in ./node_modules/terminal-kit/lib/TextBuffer.js

Module parse failed: Unexpected token (1594:90)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
|
|
> TextBuffer.prototype.object2attr = function( attrObject , colorNameToIndex = this.palette?.colorNameToIndex , legacyColor = false ) {
|       return this.ScreenBuffer.object2attr( attrObject , colorNameToIndex , legacyColor ) ;
| } ;

 @ ./node_modules/terminal-kit/lib/termkit-no-lazy-require.js 69:21-49
 @ ./src/terminal/terminal.ts
 @ ./node_modules/cache-loader/dist/cjs.js??ref--14-0!./node_modules/babel-loader/lib!./node_modules/ts-loader??ref--14-2!./node_modules/cache-loader/dist/cjs.js??ref--0-0!./node_modules/vue-loader-v16/dist??ref--0-1!./src/components/Terminal.vue?vue&type=script&lang=ts
 @ ./src/components/Terminal.vue?vue&type=script&lang=ts
 @ ./src/components/Terminal.vue
 @ ./node_modules/cache-loader/dist/cjs.js??ref--14-0!./node_modules/babel-loader/lib!./node_modules/ts-loader??ref--14-2!./node_modules/cache-loader/dist/cjs.js??ref--0-0!./node_modules/vue-loader-v16/dist??ref--0-1!./src/components/TerminalFrame.vue?vue&type=script&lang=ts
 @ ./src/components/TerminalFrame.vue?vue&type=script&lang=ts
 @ ./src/components/TerminalFrame.vue
 @ ./node_modules/cache-loader/dist/cjs.js??ref--14-0!./node_modules/babel-loader/lib!./node_modules/ts-loader??ref--14-2!./node_modules/cache-loader/dist/cjs.js??ref--0-0!./node_modules/vue-loader-v16/dist??ref--0-1!./src/App.vue?vue&type=script&lang=ts
 @ ./src/App.vue?vue&type=script&lang=ts
 @ ./src/App.vue
 @ ./src/main.ts
 @ multi (webpack)-dev-server/client?http://192.168.86.42:8080&sockPath=/sockjs-node (webpack)/hot/dev-server.js ./src/main.ts

 error  in ./node_modules/terminal-kit/lib/document/BaseMenu.js

Module parse failed: Unexpected token (300:43)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
|                       break ;
|               case 'submenu' :
>                       if ( this.hasSubmenu && this.focusChild?.def?.items ) {
|                               this.openSubmenu( this.focusChild.value , this.focusChild ) ;
|                               if ( this.submenu ) { this.document.giveFocusTo( this.submenu ) ; }

 @ ./node_modules/terminal-kit/lib/document/RowMenu.js 32:17-43
 @ ./node_modules/terminal-kit/lib/termkit-no-lazy-require.js
 @ ./src/terminal/terminal.ts
 @ ./node_modules/cache-loader/dist/cjs.js??ref--14-0!./node_modules/babel-loader/lib!./node_modules/ts-loader??ref--14-2!./node_modules/cache-loader/dist/cjs.js??ref--0-0!./node_modules/vue-loader-v16/dist??ref--0-1!./src/components/Terminal.vue?vue&type=script&lang=ts
 @ ./src/components/Terminal.vue?vue&type=script&lang=ts
 @ ./src/components/Terminal.vue
 @ ./node_modules/cache-loader/dist/cjs.js??ref--14-0!./node_modules/babel-loader/lib!./node_modules/ts-loader??ref--14-2!./node_modules/cache-loader/dist/cjs.js??ref--0-0!./node_modules/vue-loader-v16/dist??ref--0-1!./src/components/TerminalFrame.vue?vue&type=script&lang=ts
 @ ./src/components/TerminalFrame.vue?vue&type=script&lang=ts
 @ ./src/components/TerminalFrame.vue
 @ ./node_modules/cache-loader/dist/cjs.js??ref--14-0!./node_modules/babel-loader/lib!./node_modules/ts-loader??ref--14-2!./node_modules/cache-loader/dist/cjs.js??ref--0-0!./node_modules/vue-loader-v16/dist??ref--0-1!./src/App.vue?vue&type=script&lang=ts
 @ ./src/App.vue?vue&type=script&lang=ts
 @ ./src/App.vue
 @ ./src/main.ts
 @ multi (webpack)-dev-server/client?http://192.168.86.42:8080&sockPath=/sockjs-node (webpack)/hot/dev-server.js ./src/main.ts

I am thinking that it may be due to me trying to get terminal-kit running on xterm.js, the stdin/stdout/stderr shim is needed for commander.js to work.

EDIT: Also I got this error in chrome's console, not sure if it helps

Uncaught Error: Cannot find module './Rect.js'
    at webpackEmptyContext (eval at ./node_modules/terminal-kit/lib sync recursive (app.js:1009), <anonymous>:2:10)
    at Object.get (Lazyness.js?e55f:187)
    at Object.eval (ScreenBuffer.js?ad28:86)
    at eval (ScreenBuffer.js:1802)
    at Object../node_modules/terminal-kit/lib/ScreenBuffer.js (chunk-vendors.js:3662)
    at __webpack_require__ (app.js:849)
    at fn (app.js:151)
    at Object.eval (termkit-no-lazy-require.js?0b23:67)
    at eval (termkit-no-lazy-require.js:141)
    at Object../node_modules/terminal-kit/lib/termkit-no-lazy-require.js (chunk-vendors.js:4538)

@cronvel
Copy link
Owner

cronvel commented May 24, 2021

@dustyhorizon It is caused by the optional chaining ?. operator. It seems that your setup doesn't support the latest EcmaScript features. You should be able to transpile somehow.

@dustyhorizon
Copy link
Author

dustyhorizon commented May 24, 2021

@dustyhorizon It is caused by the optional chaining ?. operator. It seems that your setup doesn't support the latest EcmaScript features. You should be able to transpile somehow.

@cronvel Thanks for the heads up, adding babel-loader for webpack targeting the module have cleared the compilation error. However the web console still shows the following error

Uncaught Error: Cannot find module './Rect.js'
    at webpackEmptyContext (eval at ./node_modules/terminal-kit/lib sync recursive (app.js:1009), <anonymous>:2:10)
    at Object.get (Lazyness.js?e55f:187)
    at Object.eval (ScreenBuffer.js?ad28:86)
    at eval (ScreenBuffer.js:1983)
    at Object../node_modules/terminal-kit/lib/ScreenBuffer.js (chunk-vendors.js:4562)
    at __webpack_require__ (app.js:849)
    at fn (app.js:151)
    at Object.eval (termkit-no-lazy-require.js?0b23:67)
    at eval (termkit-no-lazy-require.js:122)
    at Object../node_modules/terminal-kit/lib/termkit-no-lazy-require.js (chunk-vendors.js:5440)

For completeness, the following is the output from yarn serve

 warning  in ./node_modules/terminal-kit/lib/termkit-no-lazy-require.js

Critical dependency: require function is used in a way in which dependencies cannot be statically extracted

 warning  in ./node_modules/terminal-kit/lib/vte/Vte.js

Module not found: Error: Can't resolve 'child_pty' in '/Users/kennethtan/Documents/GitHub/euterpe/frontend/kuri/node_modules/terminal-kit/lib/vte'

 warning  in ./node_modules/terminal-kit/lib/termconfig/README

Module parse failed: Unexpected token (3:0)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
|
|
> <terminal>.js refers to the real terminal application, e.g. gnome-terminal, konsole, ...
|
| <terminal>.generic.js refers to a fail-safe version of a terminal used when we got the terminal identifier

 @ ./node_modules/terminal-kit/lib/termconfig sync ^\.\/.*$
 @ ./node_modules/terminal-kit/lib/Terminal.js
 @ ./node_modules/terminal-kit/lib/termkit-no-lazy-require.js
 @ ./src/terminal/terminal.ts
 @ ./node_modules/cache-loader/dist/cjs.js??ref--14-0!./node_modules/babel-loader/lib!./node_modules/ts-loader??ref--14-2!./node_modules/cache-loader/dist/cjs.js??ref--0-0!./node_modules/vue-loader-v16/dist??ref--0-1!./src/components/Terminal.vue?vue&type=script&lang=ts
 @ ./src/components/Terminal.vue?vue&type=script&lang=ts
 @ ./src/components/Terminal.vue
 @ ./node_modules/cache-loader/dist/cjs.js??ref--14-0!./node_modules/babel-loader/lib!./node_modules/ts-loader??ref--14-2!./node_modules/cache-loader/dist/cjs.js??ref--0-0!./node_modules/vue-loader-v16/dist??ref--0-1!./src/components/TerminalFrame.vue?vue&type=script&lang=ts
 @ ./src/components/TerminalFrame.vue?vue&type=script&lang=ts
 @ ./src/components/TerminalFrame.vue
 @ ./node_modules/cache-loader/dist/cjs.js??ref--14-0!./node_modules/babel-loader/lib!./node_modules/ts-loader??ref--14-2!./node_modules/cache-loader/dist/cjs.js??ref--0-0!./node_modules/vue-loader-v16/dist??ref--0-1!./src/App.vue?vue&type=script&lang=ts
 @ ./src/App.vue?vue&type=script&lang=ts
 @ ./src/App.vue
 @ ./src/main.ts
 @ multi (webpack)-dev-server/client?http://192.168.86.42:8080&sockPath=/sockjs-node (webpack)/hot/dev-server.js ./src/main.ts

I assume that child_pty is not required for use in a browser target + xterm.js?

@dustyhorizon dustyhorizon reopened this May 24, 2021
@cronvel
Copy link
Owner

cronvel commented May 28, 2021

@dustyhorizon You can safely ignore child_pty and probably the whole vte directory.
I don't understand why there is an error with the ./Rect.js require.

@cronvel
Copy link
Owner

cronvel commented May 28, 2021

@dustyhorizon I can eventually create a browser build, if it's not too much time consuming. But as a back-end developer I would use Browserify instead of webpack (easiest for me to set up).
Would it be ok for you?

cronvel added a commit that referenced this issue May 28, 2021
@cronvel
Copy link
Owner

cronvel commented May 28, 2021

@dustyhorizon Ok, v2.1.4 now have a browser build, that you can find in the browser/ directory, along with the minified version. I have nothing to check if it works, so I would really appreciate if you could give me some feedback if you get it work with Xterm.js.

@dustyhorizon
Copy link
Author

dustyhorizon commented May 30, 2021

@dustyhorizon Ok, v2.1.4 now have a browser build, that you can find in the browser/ directory, along with the minified version. I have nothing to check if it works, so I would really appreciate if you could give me some feedback if you get it work with Xterm.js.

Hey @cronvel thanks for working on this. Unfortunately I am still not able to get it to work (erroring at "Cannot find module ./Rect.js"). I tried troubleshooting and it seems that its erroring when trying to lazy require ./Rect.js via this function

I am using Webpack as it came with the vue-cli project generator (via vue create) as there is no option for browserify.

Appreciate you looking into this!

The following is the error output on console and the lines it refers to if it helps

Uncaught Error: Cannot find module './Rect.js'
    at o (termkit.js?c880:1)
    at eval (termkit.js?c880:1)
    at Object.get (termkit.js?c880:30063)
    at Object.eval (termkit.js?c880:1058)
    at Object.eval (termkit.js?c880:2770)
    at Object.3../misc.js (termkit.js?c880:2770)
    at o (termkit.js?c880:1)
    at eval (termkit.js?c880:1)
    at Object.eval (termkit.js?c880:21629)
    at Object.eval (termkit.js?c880:21697)

termkit.js?c880:30063
termkit.js?c880:1058

@cronvel
Copy link
Owner

cronvel commented May 31, 2021

@dustyhorizon Sorry for that no-brainer patch... This one should work: v2.1.5.

@dustyhorizon
Copy link
Author

@dustyhorizon Sorry for that no-brainer patch... This one should work: v2.1.5.

@cronvel have managed to get it working without errors but seems like mocking stdin/stdout with xterm.js doesn't work well in the browser. Managed to get output working but inputs aren't, probably an issue with how I mocked the write prototype. Will continue to fiddle more once I am done with this other project I am doing though.

Heres a screengrab, thanks for the help so far!

image

@cronvel
Copy link
Owner

cronvel commented Jun 1, 2021

@dustyhorizon Have in mind that chunk's split in the stream have meaning. E.g. while ESC starts escape sequences, if it is at the end of a chunk it will be interpreted as ESC key press. That may sound strange, but that's how STDIN work. So any escape sequence should be written in one go.

@wxfred
Copy link

wxfred commented Sep 3, 2022

@cronvel Hi, is there any demo in using the browser version? I can't get it working.

TypeError: Cannot read properties of undefined (reading 'isTTY')
    at Object.exports.guessTerminal (termkit.js?b261:8273:1)

there is no process in the web.

// termkit.js
exports.guessTerminal = function( unpipe ) {
  var envVar , version ;

  var isSSH = !! process.env.SSH_CONNECTION ;
  var isTTY = !! process.stdout.isTTY ;

How to reproduce the error:
1.Open a terminal, install vue-cli globally
npm install -g @vue/cli

2.Create a new project with default settings, install terminal-kit, and run

vue create terminaltest
cd ./terminaltest
npm install terminal-kit --save
npm run serve

3.Open http://localhost:8080/ on your Chrome, currently, no error

4.Import terminal-kit in Home.vue

...
</template>
<script>
import termkit from 'terminal-kit/browser/termkit'
export default {
...
  mounted() {
    console.log(termkit)
  },

5.Check the console on your Chrome Develpment Tools (press F12 to open it on Chrome)

@cronvel
Copy link
Owner

cronvel commented Sep 8, 2022

You should use the build located in terminal-kit/browser/termkit.min.js.
Since it's built with Browserify, there are replacements for process, and other Node.js things.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants