First, clone this repository to your local machine, e.g.
git clone https://github.com/tangrams/tangram-play.git && cd tangram-play
Tangram Play uses Yarn to guarantee dependency versions are locked and consistent across environments. If you have installed Yarn, run the following command in this repository's root directory:
yarn
If you intend to contribute to Tangram Play, please use Yarn to guarantee consistent dependency installation. However, Yarn is not required to run Tangram Play. If you want to keep using npm
, you may continue to do this instead:
npm install
Yarn / npm installs all the required Node.js modules and dependencies, and immediately compiles everything. You should only need to do once after cloning, or every once in a while when dependencies change.
Note: For the remainder of this document, we will continue to use npm
commands, but the yarn
CLI equivalent will work as well.
For day-to-day development, we build the client-side bundles using Gulp. You may need to install this command line tool globally if you do not already have it (and you may need to do this with sudo
). Unless other specified, assume this and all other command line instructions in this document are run from the repository's root directory.
npm install -g gulp
To build JavaScript and CSS once, run:
gulp build
The default behavior of gulp
uses Browsersync to watch for source file changes, rebuild client-side bundles, and automatically update browser tabs. For convenience, this maps to a standard npm
run script command:
npm start
When run, a local server will be opened on http://localhost:8080/
. You may adjust this port by configuring gulpfile.js
. In addition, you may access the Browsersync UI (default location is http://localhost:8081/
). Browsersync will automatically reload when JavaScript or the app's entry index.html
is edited. CSS files will stream into the application without a reload. Tangram Play will save some elements of application state, such as map position, last scene content, and last editor position even while reloading. You may safely kill the BrowserSync server process at any time by hitting Ctrl-C.
If you want to build and watch JavaScript and CSS assets without Browsersync, you can do so with this gulp
task:
gulp watch
You can then run a local server manually. The app is a static site, and can be viewed by any static fileserver, such as Python's SimpleHTTPServer or Node's http-server module.
After downloading this repository and running npm install
, you can start a web server in its directory:
cd public
python -m SimpleHTTPServer 8080
If that doesn't work, try:
cd public
python -m http.server 8080
Then navigate to: http://localhost:8080/
After downloading this repository and running npm install
, then install http-server
:
npm install -g http-server
Then, from the repository's root directory, run:
http-server
Then navigate to: http://localhost:8080/
You may have Tangram scene files locally and want to load them into a local build of Tangram Play. If you attempt to load them from http://localhost:xxxx
where xxxx
is a different port from a local Tangram Play, browsers will block requests unless CORS is enabled. The easiest way to run a local server with CORS enabled is with Node's http-server module.
http-server -p xxxx --cors # Set -p (port) to whatever you like
The public/scripts/
and public/stylesheets
directories are not committed to the source code. We use Circle.CI's configuration to compile all the files for deployment.
Circle.CI also runs tests and lints code. If the code fails to lint, or tests fail, Circle.CI will refuse to deploy that code.
Create a new topic branch for the feature or patch you are committing, either on this repository (for contributors) or in a fork of the project. When your code is ready for review, commit and push your changes to your branch, and then submit a new pull request to the master
branch of this project.
Please wait for Circle.CI to run its tests and report that all tests are passing. Additionally, there may be other comments from other contributors. Contributors should also have access to Precog, which enables previews of the code without needing to build and preview locally. Once approved, the branch will be merged into the codebase, and the topic branch will be deleted if it is in this repository.
See Release/Deployment plan in the wiki.
Stylesheets are processed by PostCSS with the CSSNext plugin.
Like the Tangram library itself, JavaScript is written in ES6 (aka ECMAScript 2015). It is transpiled by Babel and modules are bundled with Browserify.
Tangram Play has low test coverage, but we intend for this to improve dramatically over time. Pull requests that have tests included are more likely to be reviewed and approved quicker. The test stack is very similar to Tangram: it uses the Karma test runner, the Mocha test framework, the Chai assertion library (with the assert
assertion style), and Sinon for stubs and mocks. The test environment is also transpiled with Babel and assumes the presence of ES2015 language features.
To run tests:
npm run karma
You may need access to debugging features for Tangram while using Tangram Play. To help you do this, two query string parameters are supported:
Append ?debug=true
to the URL to load the tangram.debug.js
version of the Tangram library that Tangram Play would normally be loading. The debug version of Tangram is unminified, which allows easier-to-follow stack traces and code examination. In addition, setting this flag turns out Tangram Play's debug mode internally (which currently does nothing, but can be used for debug features later). For instance:
https://mapzen.com/tangram/play/?debug=true
If you want to load an entirely different version of Tangram (including local test builds) use the parameter ?lib={url}
. The {url}
must be a fully-qualified URL (no shorthand values exist) and the library must be hosted on either localhost
or mapzen.com
in order to prevent malicious URLs from loading arbitrary JavaScript sources from third-party hosts. Please note that some of Tangram Play's functionality depends on Tangram features that have been added over time (such as map feature inspection), and that older Tangram versions interacted with Leaflet in different ways (or required older versions of Leaflet), so older versions of Tangram may introduce other errors that Tangram Play is not designed to catch.
NOTE: When loading local test builds from localhost
, your browser may block content from insecure (non-SSL) protocols.
https://mapzen.com/tangram/play/?lib=https://mapzen.com/tangram/0.10/tangram.debug.js
You can use both query parameters at the same time. Specifying lib={url}
will override the library loaded for debug=true
, but will still turn on Tangram Play's internal debug flag. (And specifying lib=
without debug=true
will not turn on the debug flag.)
https://mapzen.com/tangram/play/?lib=https://mapzen.com/tangram/0.10/tangram.debug.js&debug=true
When a different library has been loaded in this way, a notice will be posted in the console. If a lib={url}
is not hosted on localhost
or mapzen.com
, Tangram Play will post an error in the console and proceed to load the default Tangram library. Other errors (such as a 404 Not Found response) will cause Tangram Play to throw an error and stop loading.
We use EditorConfig to automatically set editor settings for this project. For your text editor you may need to download a plugin to enable this.
Tangram Play adopts the Airbnb Javascript style guide for Javascript, which is using the ESLint engine. Some rules are overridden globally within .eslintrc
, with rationale, when it does not apply to our project or is overly strict. Some overridden rules are warnings instead of errors, while some are simply allowed.
Rule violations that occur rarely, but for good reason, can be overridden by using the eslint-disable
, eslint-disable-line
, or eslint-disable-next-line
directives to keep linter output clean. These should not be used liberally to avoid writing code to the guidelines, but should be considered when obeying the rule would result in overly unreadable and unmaintainable code. Ideally, use eslint-disable-next-line
with the rule that is being overridden because this is more readable, e.g.
// eslint-disable-next-line no-use-before-define
EventEmitter.unsubscribe('mapzen:sign_in', clickOpenFromCloud);
As opposed to, this, which might line wrap:
EventEmitter.unsubscribe('mapzen:sign_in', clickOpenFromCloud); // eslint-disable-line no-use-before-define
We use Stylelint and build on stylelint-config-standard
for linting CSS.
To run the linter, there is an npm
script that runs ESLint and Stylelint on non-vendor-sourced files.
npm run lint
You may also run commands to lint JavaScript or CSS separately.
npm run lint-js
npm run lint-css