lahmatiy/component-inspector

`Open file in editor` is not supported

sergey-lapin opened this issue · 53 comments

I have managed to get all features working except opening in sublime by click. I guess I need basisjs-tools for that also, but not sure.
BTW, thanks for sharing this!

Did you read this section https://github.com/lahmatiy/component-inspector#opening-file-in-editor?
It's a little bit messy now. But I'm planing to improve it next few days. Feedback is welcome.

Using basisjs-tools is not a single option anymore. You can use express-open-in-editor for example.

Ahh missed this section. Will try that

Running server to open files seems like overkill, but I understand that browser has not got permissions to do such stuff. Did you think about any workaround? At least we can make some cli tool to run this server so it could be more convenient for end user.

Yep, browsers are limited in interaction with your OS by some sort of requests. So any kind of server is required.
As I understand, you propose some build-in server. I'm not sure it's a good idea. But simple server as separate solution with certain functionality sounds good to me. As you can see in #5, besides open-in-editor feature such server could provide extract-source-fragment feature. Is it help solve you problem?
Also you can implement your own simple server, and use express-open-in-editor as request handler or as basis for your implementation.

No I don't what 'buildin' server rather cli tool that would be installed by user globally. Like npm i open-server -g && open-server serve. Because making some folder and putting express server code manually in it is a rutine and I am sure that I will forget where it is. And with cli tool server instalation, uninstalation, start and stop will be controlled from cli.

npm i basisjs-tools -g && basis server

;)

Ahh great that what I needed. Could you add this in component-inspector readme?

I tried

npm i basisjs-tools -g && basis server

Currently when I click on something in component-inspector I have XMLHttpRequest with this url

http://localhost:8000/open-in-editor?file=/components/TodoItem.js%3A60%3A7%3A65%3A12

(I setted window.OPEN_FILE_URL = 'http://localhost:8000' + '/open-in-editor' )

So I suppose basis server should run in same place as hosting server - I did that.
When I try

http://localhost:8000/open-in-editor?file=/components/TodoItem.js%3A60%3A7%3A65%3A12

in browser
I get

File /Users/sergeylapin/redux-devtools-gentest-plugin/examples/todomvc/open-in-editor not found

This

http://localhost:8000/components/TodoItem.js

correctly returns body of TodoItem.js file

When basisjs-tools server used you don't need set OPEN_FILE_URL setting. Actually OPEN_FILE_URL is fallback.
I will update readme soon with those details.

If I don't do window.OPEN_FILE_URL = 'http://localhost:8000' + '/open-in-editor'; and only do basis server I get ``Open file in editor is not supported

Well, if basis server used it should serve all statics or be a proxy. If you want to use some server just for file opening it isn't suitable. But this kind of server will soon be created.

If you developing something you already use dev-server. Isn't it? May you provide some details about using tools?

Sure I use webpack, mostly its configuration close to https://github.com/erikras/react-redux-universal-hot-example

Do you use webpack dev-server to serve statics?

Well, you can use express-open-in-editor as other middlewares you use. No extra server required.

Can I use it like this?

var webpack = require('webpack');
var WebpackDevServer = require('webpack-dev-server');
var config = require('./webpack.config');

var openInEditor = require('express-open-in-editor');

var app = new WebpackDevServer(webpack(config), {
  publicPath: config.output.publicPath,
  hot: true,
  historyApiFallback: true,
  stats: {
    colors: true
  }
});

app.use(openInEditor());

app.listen(3000, 'localhost', function (err) {
  if (err) {
    console.log(err);
  }

  console.log('Listening at localhost:3000');
});

I have tried to go http://localhost:3000/open-in-editor?file=/components/TodoItem.js with no result. Nothing in logs as well.

Oh.. You on the right way. But I suppose webpack's default handlers don't allow to run openInEditor handler :-/

@Lapanoid, that should be possible. My guess, some webpack handler stops triggering middleware at some point (does not call next()). You could investigate dev server's source here: https://github.com/webpack/webpack-dev-server/blob/master/lib/Server.js

Another approach would be to check if any middleware is triggered, when we use app.use(). Smth like this:

var webpack = require('webpack');
var WebpackDevServer = require('webpack-dev-server');
var config = require('./webpack.config');

var app = new WebpackDevServer(webpack(config), {
  publicPath: config.output.publicPath,
  hot: true,
  historyApiFallback: true,
  stats: {
    colors: true
  }
});

app.use(function(req, res, next) {
  console.log('Middleware triggered');
  next();
});

app.listen(3000, 'localhost', function (err) {
  if (err) {
    console.log(err);
  }

  console.log('Listening at localhost:3000');
});

@Filipovskii Checked that and I don't have Middleware triggered in logs so I guess you are right and WebpackDevServer don't call middleware

@Filipovskii this is the right way to add middleware to webpack dev server webpack/webpack-dev-server#285 (comment)

var webpack = require('webpack');
var WebpackDevServer = require('webpack-dev-server');
var config = require('./webpack.config');

var openInEditor = require('express-open-in-editor');

var server = new WebpackDevServer(webpack(config), {
  publicPath: config.output.publicPath,
  hot: true,
  historyApiFallback: true,
  stats: {
    colors: true
  },
  setup: function (app) {
    app.use(openInEditor())
  }
});

server.listen(3000, 'localhost', function (err) {
  if (err) {
    console.log(err);
  }

  console.log('Listening at localhost:3000');
});

However I have these errors when I do that

GET http://localhost:3000/open-in-editor?file=/components/TodoItem.js%3A60%3A7%3A65%3A12 y @ react.js:203La.y.js.F.exports.openFile @ react.js:204La.11.js.n.subclass.action.inspect @ react.js:233La.7.js.b.templateAction @ react.js:277(anonymous function) @ react.js:48u @ react.js:336
react.js:203 

Uncaught NetworkError: Failed to execute 'send' on 'XMLHttpRequest': Failed to load 'http://localhost:3000/open-in-editor?file=/components/TodoItem.js%3A60%3A7%3A65%3A12'.

What does the Network tab say? What's the HTTP response?

When I click on something to open editor, ui stay frozen and I have pending request in Network. Can't reproduce these errors for now.

Even can't kill the tab =/

Oh I get it, this errors happens when I kill server. Not clear to me why ui is frozen even with pending request

Looks like middleware is not calling response.end() is that possible, @lahmatiy ?

Middleware source is here: https://github.com/lahmatiy/express-open-in-editor/blob/master/index.js
I believe it calls res.end() in any case, and one next(). Probably problems:

  • next handler doesn't call res.end()
  • openInEditor doesn't resolve promise somehow

And, blame on me, I make synchonous XHR requests to open files by mistake https://github.com/lahmatiy/component-inspector/blob/master/src/inspector/api/file.js#L32 :(

Fix requests to be async 7a120fe

@Lapanoid Thanks to your feedback, instructions for using express-open-in-editor with webpack-dev-server was added: https://github.com/lahmatiy/express-open-in-editor#using-with-webpack-dev-server

It remains to improve feature description in readme (#7)

Did not tryied this. Did you published latest to npm?

Not yet. Coming soon. Maybe tomorrow.

Published \o/
Is there any open questions?

No, I can't as still have this issue. Can I build not minified lib somehow with basis to add some logs and test this?

You can run dev version w/o build (https://github.com/lahmatiy/component-inspector#implementation)

<script src="node_modules/component-inspector/node_modules/basisjs/src/basis.js" basis-config="
  devpanel: false,
  modules: {
    react: {
      autoload: true,
      filename: 'node_modules/component-inspector/src/react.js'
    }
  }
"></script>

@lahmatiy I am not passing this check when I try to click on something;

function isOpenFileSupported(){
  if (openFile) {
    return true;
  }

  var basisjsTools = global.basisjsToolsFileSync || basis.devtools;
  if (basisjsTools && typeof basisjsTools.openFile == 'function') {
    openFile = function(filename){
      openFileByBasisjsTools(basisjsTools, filename);
    };
    return true;
  }

  if (typeof OPEN_FILE_URL == 'string') {
    openFile = openFileByUrl;
    return true;
  }
}

global.basisjsToolsFileSync and basis.devtools are undefined.

If we are using the same example but getting different results.. Are you sure that you don't have some global deps?

global.basisjsToolsFileSync and basis.devtools are used when running on basisjs-tools server. Don't care about it.

You should define global OPEN_FILE_URL variable, as explained here: https://github.com/lahmatiy/component-inspector#opening-file-in-editor.

Using webpack you can define it with DefinePlugin plugin:

    plugins: [
        ...
        new webpack.DefinePlugin({
            OPEN_FILE_URL: '"/open-in-editor"'
        })
    ]

@lahmatiy I tried that and I am running into another issue with it.

When I click on something to open editor, ui stay frozen and I have pending request in Network.

You made XMLHttpRequest async so ui is not frozen now, but the problem remains.

When you go to
http://localhost:3000/open-in-editor?file=/components/MainSection.js%3A49%3A13%3A49%3A64
in browser what so you see? In my case - I don't get any answer and I don't open editor (sublime).

PS. Guess I need to debug 'open-in-editor' to find out.

I got what problem is. When you start server you should get:

$ npm start

> todomvc@0.0.0 start C:\git\component-inspector\examples\react-todomvc
> node server.js

open-in-editor configure error:  Editor is not specified
Listening at localhost:3000

So problem is, open-in-editor doesn't found what editor to use.
See express-open-in-editor [usage](https://github.com/lahmatiy/express-open-in-editor#usage] section. You can specify it via ENV or run command like this (on mac):

EDITOR=sublime npm start

More details here

Probably we should throw exception on editor configure error.
I'll update docs to highlight possible problems.

I have currently this

node server.js
Listening at localhost:3000

no

open-in-editor configure error: Editor is not specified

And no any other errors or warnings?

Did you try open http://localhost:3000/open-in-editor?file=/components/MainSection.js%3A49%3A13%3A49%3A64 in your browser? What is response? Should be "OK".

No response at all.

I debuged express-open-in-editor

    console.log('8')
    opener.open(filename).then(
      function() {
        console.log('9')
        res.statusCode = 200;
        res.end('OK');
      },
      function(e) {
        console.log('10')
        fail(500, 'open-in-editor error: ' + e);
      }
    );
    console.log('11')

my output when I click on smth in inspector is

8
11

no 10 or 9

So opener.open(filename) does not fail nor succeed, so I have no feedback in logs and when I open http://localhost:3000/open-in-editor?file=/components/MainSection.js%3A49%3A13%3A49%3A64 as well.

Also every time when I click on something some 'nano' proc inited and when I kill it I get

GET http://localhost:3000/open-in-editor?file=/components/TodoItem.js%3A60%3A7%3A65%3A12 500 (Internal Server Error)

BTW I am a mac user =)

@lahmatiy
I think we are close to finish this issue)

Should I be able to run this from terminal?

sublime -r -g components/TodoItem.js:60:7

getting

zsh: command not found: sublime

Hm... how do you setup EDITOR?
It should correctly fails on command error. I'll check it. Thank you for the clue.

running with

EDITOR=sublime npm start

don't work I have

"nano" "components/TodoItem.js:60:7"

if I do that.

I ended with

 setup: function (app) {
    app.use(openInEditor({cmd: 'sublime -r -g'}))
  }

In this case I get

GET http://localhost:3000/open-in-editor?file=/components/TodoItem.js%3A60%3A7%3A65%3A12 500 (Internal Server Error)

Basically because I can't run

sublime -r -g components/TodoItem.js:60:7

in terminal at all

sublime command is available in cli? usually it's subl
Sublime has no -r and -g options, it's for VS Code only.

Just try open sublime by command in terminal. Then use this command for open-in-editor.
subl (or another name) could be setup by youself: http://olivierlacan.com/posts/launch-sublime-text-3-from-the-command-line/

Ok this helped
Bottom line:

I needed to make this

ln -s "/Applications/Sublime Text.app/Contents/SharedSupport/bin/subl" /usr/local/bin/sublime

and this

 setup: function (app) {
    app.use(openInEditor({cmd: 'sublime'}))
  }

to make open-in-editor feature worked

It's better to setup editor by EDITOR or other ENV variables. Because other developers could use another editors.
Also open-in-editor will try to find editor by known locations in feature, if EDITOR or other settings is not set.
Thank you for feedback. I'll improve documentation and will think about how to make it simpler.

I think this should be at the top of readme as any other info about usage
https://github.com/lahmatiy/component-inspector#opening-file-in-editor
as people will try to use it before join to any development on this or do some not trivial stuff with it.

It's better to setup editor by EDITOR or other ENV variables.

this EDITOR=sublime npm start is not working for me as I wrote before