Description
The GopherJS project has developed the gopherjs
tool. Its CLI mimics a lot of the commands that go
tool (import path cmd/go
, in GOROOT) offers, in addition to one new command serve
(see #268). However, it's missing some features of the real cmd/go
(see issues labeled cmd/go for some examples).
Instead of continuing to develop and maintain the gopherjs
tool ourselves, I propose we replace the custom implementation of gopherjs
with a modified fork of the real cmd/go
that has 2 changes cherry-picked on top. All existing functionality would be preserved, gaining missing features, fixing bugs, and reducing overall maintenance cost. The only functionality that the current gopherjs
tool offers but cmd/go
doesn't is the serve
command, and we will preserve it in some way (details to be determined).
Plan
At a high level, my proposed plan is:
- Wait for Go 1.6 release, or combine this plan with adding suppport for Go 1.6.
- Create a fork of
cmd/go
. - Create a change that can be cherry-picked (or rebased) on top of latest upstream
cmd/go
that makes the command go-gettable.- This is a small change.
- Create a change that can be cherry-picked (or rebased) on top that adds support for -compiler=gopherjs value.
- This is a larger change, but it can be done cleanly and will result in significant simplification in the work that GopherJS needs to do, stripping away a lot of its responsibility as a build tool, leaving only the compilation and linking to be done.
- Continue to make the augmented
cmd/go
available and maintain it by simply taking the latest upstream code and rebasing the 2 cherry-picked changes on top.- When the plan is complete and the changes are reviewed and made clean, and everything proves to be stable, we can attempt to make a CL to merge the -compiler=gopherjs support addition upstream into core Go repository, and learn if there are any blockers from making that possible. If not accepted, we can continue to maintain the forked tool ourselves with low maintenance overhead.
The end result will be a fully capable cmd/go
-like command that will support compiling with GOARCH=js
set. It will be able to go run
and go test
by setting -exec=node
. It will resolve all these issues and simplify original code that GopherJS project has to maintain.
Research and viability
I have explored this idea recently by attempting to do this during a 48-hour Gopher Gala 2016 hackathon. The project, which was mostly me learning about how cmd/go
is structured and works, can be seen here:
https://github.com/gophergala2016/cmd-go-js#readme
It partially implements what I have described above, but not completely. Due to time constraints, I did not attempt to make changes to gopherjs
binary and simply used it as it exists today. This allowed me to implement go build
and go run
, but not the other commands.
To have all other features work as expected, the entire toolchain
interface needs to be implemented correctly.
You can read the README of the linked project for additional details and observations.
Mockup
Here's a mockup demonstrating how the new build tool for GopherJS would look like:
One possible simplification might be that setting -compiler=gopherjs
explicitly won't be needed when GOARCH=js
is already set. That would allow typed commands to be shorter.
Summary
By implementing this plan, the end result is expected to:
- Continue to provide all existing functionality, while resolving many bugs and implementing missing functionality of the
cmd/go
build tool. - Remove most of the current "build tool" code, allowing GopherJS to focus on being a pure Go compiler and linker for JavaScript architecture.
- Reduce the total maintenance cost since it's expected the effort to rebase the 2 clean changes on top of
cmd/go
will be much smaller than to keep developing and maintaininggopherjs
tool ourselves. - A real
go
tool should be more familiar and friendly to new people, since most Go developers are very familiar with thecmd/go
tool and its flags.- Compiling with GopherJS can be seen just like cross-compiling to another OS/architecture, which is a common and well understood concept.
I've discussed this plan with @neelance and agreed it sounds favorable. What's next is to attempt to execute it and ensure no major blocking issues come up.