Làm cách nào để tải tập lệnh của tôi vào REPL của node.js?


137

Tôi có một kịch bản foo.js chứa một số chức năng mà tôi muốn chơi trong REPL.

Có cách nào để nút thực thi tập lệnh của tôi và sau đó nhảy vào REPL với tất cả các quả cầu được khai báo, như tôi có thể với python -i foo.pyhoặc ghci foo.hskhông?

Câu trả lời:


179

Vẫn không có gì tích hợp để cung cấp chức năng chính xác mà bạn mô tả. Tuy nhiên, một cách khác để sử dụng requirenó để sử dụng .loadlệnh trong REPL, như:

.load foo.js

Nó tải tập tin theo từng dòng giống như bạn đã gõ nó trong REPL. Không giống như requiređiều này gây ô nhiễm lịch sử REPL với các lệnh bạn đã tải. Tuy nhiên, nó có lợi thế là có thể lặp lại vì nó không được lưu trữ như thế nào require.

Cái nào tốt hơn cho bạn sẽ phụ thuộc vào trường hợp sử dụng của bạn.


Chỉnh sửa: Nó có khả năng áp dụng hạn chế vì nó không hoạt động ở chế độ nghiêm ngặt, nhưng ba năm sau tôi đã biết rằng nếu tập lệnh của bạn không có 'use strict', bạn có thể sử dụng evalđể tải tập lệnh của mình mà không làm ô nhiễm lịch sử REPL:

var fs = require('fs');
eval(fs.readFileSync('foo.js').toString())

Điều gì xảy ra nếu tôi muốn thả vào thay thế bên trong một cuộc gọi lại async?
Chet

2
@Chet Bạn viết lên một câu hỏi StackOverflow mới nếu câu hỏi của bạn không khớp với câu hỏi hiện có :-)
vossad01

@Chọn bạn có thể .load một tệp khác với (async () => {thêm mã}) (); và nó sẽ chia sẻ cùng một thế giới.
Nurettin

Mẹo nếu bạn đang sử dụng macOS (có thể cả những người khác nữa). Bạn có thể nhập ".load" (lưu ý khoảng trắng) vào REPL và kéo / thả tệp vào Terminal từ Finder để thêm đường dẫn chính xác vào lệnh của bạn. Điều này rất hữu ích nếu các tệp bạn đang làm việc giảm xuống một vài cấp.
jamesnotjim

35

tôi luôn sử dụng lệnh này

node -i -e "$(< yourScript.js)"

hoạt động chính xác như trong Python mà không cần bất kỳ gói nào.


1
Có ai biết làm thế nào để làm việc này trong windows cmd? Tôi đã làm cho nó hoạt động trong bash, nhưng không phải cửa sổ.
Sharpiro

@Sharpiro: Nếu bạn cài đặt Git thì bạn có tùy chọn cài đặt mini-UNIX vào PC Windows của mình. Ý tôi là phân phối bình thường của Git cho Windows.
Juan Lanus

Một điều gây khó chịu về điều này là Node.js sẽ in dấu nhắc thay thế và sau đó chạy tập lệnh của bạn, do đó, bất kỳ đầu ra nào cũng bị kẹt sau dấu nhắc. stackoverflow.com/a/4589349435338165 không có vấn đề này nhưng đối với chức năng giải pháp đó phải được gán rõ ràng cho các biến để kết thúc trong không gian tên thay thế, vì vậy cũng không tốt lắm.
Radon Rosborough

10

Tôi đã tạo Vorpal.js , xử lý vấn đề này bằng cách biến nút thêm của bạn thành CLI tương tác. Nó hỗ trợ tiện ích mở rộng REPL, giúp bạn thả REPL trong bối cảnh ứng dụng đang chạy.

var vorpal = require('vorpal')();
var repl = require('vorpal-repl');

vorpal
  .delimiter('myapp>')
  .use(repl)
  .show()
  .parse(process.argv); 

Sau đó, bạn có thể chạy ứng dụng và nó sẽ rơi vào REPL.

$ node myapp.js repl
myapp> repl: 

8

Một cách khác là xác định các chức năng đó là toàn cầu.

global.helloWorld = function() { console.log("Hello World"); }

Sau đó tải trước tệp trong REPL dưới dạng:

node -r ./file.js

Sau đó, chức năng helloWorldcó thể được truy cập trực tiếp trong REPL.


8

Tôi đã tạo replpad vì tôi cảm thấy mệt mỏi khi tải lại tập lệnh nhiều lần.

Đơn giản chỉ cần cài đặt nó qua: npm install -g replpad

Sau đó sử dụng nó bằng cách chạy: replpad

Nếu bạn muốn nó xem tất cả các tệp trong hiện tại và tất cả các thư mục con và đưa chúng vào thay thế khi chúng thay đổi, hãy làm: replpad .

Kiểm tra các video trên trang web để có ý tưởng tốt hơn về cách thức hoạt động và tìm hiểu về một số tính năng hay khác mà nó có như sau:

  • truy cập tài liệu mô-đun lõi trong thay thế thông qua dox()chức năng được thêm vào mọi chức năng cốt lõi, nghĩa làfs.readdir.dox()
  • truy cập readmes mô-đun người dùng trong thay thế thông qua dox()chức năng được thêm vào mỗi mô-đun được cài đặt qua npm, tức làmarked.dox()
  • mã nguồn được tô sáng của hàm truy cập , thông tin về nơi hàm được xác định (tệp, vải lanh ) và nhận xét hàm và / hoặc jsdocs khi có thể thông qua thuộc srctính được thêm vào mọi hàm, nghĩa làexpress.logger.src
  • hỗ trợ scriptie-talkie (xem.talklệnh)
  • thêm lệnh và phím tắt
  • ràng buộc chính vim
  • hỗ trợ bản đồ chính
  • kết hợp parens thông qua plugin token phù hợp
  • nối thêm mã được nhập vào thay thế trở lại tập tin thông qua phím tắt hoặc .appendlệnh

Xem: https://github.com/thlorenz/replpad


Tôi đã phải khắc CXX=clang++ npm install replpadphục lỗig++: error: unrecognized command line option '-stdlib=libc++'
ShadSterling

Nhưng sau đó khi tôi chạy thì nó thất bại với# # Fatal error in ../deps/v8/src/api.cc, line 1248 # Check failed: !value_obj->IsJSReceiver() || value_obj->IsTemplateInfo(). # Illegal instruction: 4
ShadSterling

5

Tại sao không tải tập tin vào một nút tương tác thay thế?

node -h
-e, --eval script          evaluate script
-i, --interactive          always enter the REPL even if stdin

node -e 'var client = require("./build/main/index.js"); console.log("Use `client` in repl")' -i

Sau đó, bạn có thể thêm vào script.json

"repl": "node -e 'var client = require(\"./build/main/index.js\"); console.log(\"Use `client` in repl\")' -i",

thử nghiệm bằng nút v8.1.2


2
tại sao không chỉ node -i -r "./build/main/index.js"?
Z. Khullah

4

Hiện tại bạn không thể làm điều đó trực tiếp, nhưng bạn có thể mylib = require('./foo.js')trong REPL. Ghi nhớ các phương thức được xuất, không được khai báo là toàn cục.


Tôi thấy điều này thích hợp hơn .load my_work.js, mặc dù yêu cầu một số exports.working_var = ...khai báo bổ sung , bởi vì các barf REPL trên một số loại javascript hoàn toàn hợp lệ, như các bình luận đa dòng (ít nhất là với readlinecấu hình của tôi ).
chbrown

4

replpad Thật tuyệt, nhưng để tải tệp vào nút nhanh chóng và dễ dàng, nhập biến của nó và bắt đầu thay thế, bạn có thể thêm đoạn mã sau vào cuối tệp .js của mình

if (require.main === module){
    (function() {
        var _context = require('repl').start({prompt: '$> '}).context;
        var scope = require('lexical-scope')(require('fs').readFileSync(__filename));
        for (var name in scope.locals[''] )
            _context[scope.locals[''][name]] = eval(scope.locals[''][name]);
        for (name in scope.globals.exported)
            _context[scope.globals.exported[name]] = eval(scope.globals.exported[name]);
    })();
}

Bây giờ nếu tệp của bạn đang src.jschạy, node src.jssẽ khởi động nút, tải tệp, bắt đầu REPL và sao chép tất cả các đối tượng được khai báo varở cấp cao nhất cũng như bất kỳ toàn cầu xuất nào. Việc if (require.main === module)đảm bảo rằng mã này sẽ không được thực thi nếu src.jsđược đưa vào thông qua một requirecâu lệnh. Tôi thực tế, bạn có thể thêm bất kỳ mã nào bạn muốn được loại bỏ khi bạn đang chạy src.jsđộc lập cho mục đích gỡ lỗi bên trong ifcâu lệnh.


4

Đây là phiên bản hàm bash của câu trả lời của George :

noderepl() {
    FILE_CONTENTS="$(< $1 )"
    node -i -e "$FILE_CONTENTS"
}

Nếu bạn đặt cái này vào, ~/.bash_profilebạn có thể sử dụng nó như một bí danh, nghĩa là:

noderepl foo.js

2
Tôi đã sử dụng điều này trong nhiều tháng nay và trong quá trình chuyển đổi sang môi trường shell mới, tôi đã mất một số cài đặt của mình và phải theo dõi lại điều này một lần nữa. Vì vậy, vì tôi ở đây, tôi nghĩ tôi cảm ơn bạn vì chức năng thực sự hữu ích này.
Xaekai

3

Một đề nghị khác mà tôi không thấy ở đây: hãy thử một chút mã này

#!/usr/bin/env node
'use strict';

const repl = require('repl');
const cli = repl.start({ replMode: repl.REPL_MODE_STRICT });
cli.context.foo = require('./foo'); // injects it into the repl

Sau đó, bạn có thể chỉ cần chạy tập lệnh này và nó sẽ bao gồm foonhư một biến


1

Câu trả lời cũ

type test.js|node -i

Sẽ mở nút REPL và nhập tất cả các dòng từ test.js vào REPL, nhưng vì một số lý do, nút sẽ thoát sau khi tệp kết thúc

Một vấn đề khác là, các chức năng đó sẽ không được nâng lên.

Câu trả lời tốt hơn

node -e require('repl').start({useGlobal:true}); -r ./test2.js

Sau đó, tất cả các quả cầu được khai báo không có var trong test2.js sẽ có sẵn trong REPL

không chắc chắn tại sao var a trong phạm vi toàn cầu sẽ không có sẵn


8
Vui lòng thêm một số lời giải thích cho câu trả lời của bạn
mechnicov
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.