diff --git a/README.md b/README.md index 3bb90801c8..efcba0e7bb 100644 --- a/README.md +++ b/README.md @@ -126,6 +126,10 @@ node.js is required to build the viewer. 6. See [package.json](/package.json) for other commands available. +# Creating a dependent project + +See [examples/dependent-project](/examples/dependent-project). + # License Copyright 2016 Google Inc. diff --git a/examples/dependent-project/.gitignore b/examples/dependent-project/.gitignore new file mode 100644 index 0000000000..38f64f55ee --- /dev/null +++ b/examples/dependent-project/.gitignore @@ -0,0 +1,3 @@ +/node_modules/ +/dist/ +/npm-debug.log diff --git a/examples/dependent-project/README.md b/examples/dependent-project/README.md new file mode 100644 index 0000000000..49054f5566 --- /dev/null +++ b/examples/dependent-project/README.md @@ -0,0 +1,49 @@ +This example provides a template for making a package that depends on +neuroglancer. + +It simply binds the `o` key to set the position to the origin. + +# Setup + +This project is set up to treat the `src/neuroglancer` directory of the +neuroglancer package as if it were a part of this package. This is convenient +for simultaneous development of this project along with Neuroglancer, as it +allows standard TypeScript tooling to find definitions in Neuroglancer without +the need to regenerate `.d.ts` files. + +In [tsconfig.json](tsconfig.json), we define two module resolution aliases: +- `neuroglancer/*` maps to `src/neuroglancer` in the Neuroglancer package; +- `my-neuroglancer-project/*` maps to `src/my-neuroglancer-project/*` in this package. + +This allows any of the modules within this project to refer to other modules +using a project-relative path, as is done in neuroglancer. + +The typings file in `typings/index.d.ts` currently just includes all of the +typings for Neuroglancer dependencies by reference. If additional typings are +required, they can also be referenced from that file. + +The symbolic link from `third_party/neuroglancer` with the path +`../node_modules/neuroglancer/src/neuroglancer` is a workaround for the lack of +support for more sophisticated exclusion rules in tools like `tsserver` (used +for editor integration). It allows us to exclude `node_modules` but still +include the main neuroglancer source based on definitions in `tsconfig.json`. + +# Building + +1. If you would like this to depend on a local version of neuroglancer, you can use + the standard `link` mechanism of npm: + + - From within the neuroglancer root directory, type: + `npm link` + + - From within this directory, type: + `npm link neuroglancer` + +2. To install dependencies, run: + `npm i` + +3. To run the development server: + `npm run dev-server` + +4. To build minified output: + `npm run build-min` diff --git a/examples/dependent-project/config/webpack.config.js b/examples/dependent-project/config/webpack.config.js new file mode 100644 index 0000000000..2c4bac17b0 --- /dev/null +++ b/examples/dependent-project/config/webpack.config.js @@ -0,0 +1,22 @@ +/** + * @license + * Copyright 2016 Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +'use strict'; + +const path = require('path'); +const webpack_helpers = require('./webpack_helpers'); +module.exports = webpack_helpers.getViewerConfig( + {outputPath: path.resolve(__dirname, '../dist/dev')}); diff --git a/examples/dependent-project/config/webpack.min.js b/examples/dependent-project/config/webpack.min.js new file mode 100644 index 0000000000..8612d091d6 --- /dev/null +++ b/examples/dependent-project/config/webpack.min.js @@ -0,0 +1,22 @@ +/** + * @license + * Copyright 2016 Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +'use strict'; + +const path = require('path'); +const webpack_helpers = require('./webpack_helpers'); +module.exports = webpack_helpers.getViewerConfig( + {outputPath: path.resolve(__dirname, '../dist/min'), minify: true}); diff --git a/examples/dependent-project/config/webpack_helpers.js b/examples/dependent-project/config/webpack_helpers.js new file mode 100644 index 0000000000..2dadd16ad3 --- /dev/null +++ b/examples/dependent-project/config/webpack_helpers.js @@ -0,0 +1,44 @@ +/** + * @license + * Copyright 2016 Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +'use strict'; + +const path = require('path'); +const original_webpack_helpers = require('neuroglancer/config/webpack_helpers'); + +function modifyViewerOptions(options) { + options = options || {}; + options.resolveLoaderRoots = [ + ...(options.resolveLoaderRoots || []), + + // Allow loader modules to be resolved from node_modules directory of this + // project in addition to the node_modules directory of neuroglancer. + path.resolve(__dirname, '../node_modules') + ]; + + // This references the tsconfig.json file of this project, rather than of + // neuroglancer. + options.tsconfigPath = path.resolve(__dirname, '../tsconfig.json'); + + // This references the main.ts of this project, rather than of + // neuroglancer. + options.frontendModules = [path.resolve(__dirname, '../src/main.ts')]; + return options; +} + +exports.getViewerConfig = function (options) { + return original_webpack_helpers.getViewerConfig(modifyViewerOptions(options)); +}; diff --git a/examples/dependent-project/package.json b/examples/dependent-project/package.json new file mode 100644 index 0000000000..42df4a2186 --- /dev/null +++ b/examples/dependent-project/package.json @@ -0,0 +1,17 @@ +{ + "name": "my-neuroglancer-project", + "description": "Example project that depends on neuroglancer.", + "scripts": { + "build-min": "webpack --config ./config/webpack.min.js", + "build": "webpack --config ./config/webpack.config.js", + "dev-server": "webpack-dev-server --config ./config/webpack.config.js" + }, + "dependencies": { + "neuroglancer": "^0.0.0-beta.0", + "webpack": "^1.13.1" + }, + "devDependencies": { + "tslint-eslint-rules": "^1.2.0", + "webpack-dev-server": "^1.14.1" + } +} diff --git a/examples/dependent-project/src/main.ts b/examples/dependent-project/src/main.ts new file mode 100644 index 0000000000..1149fc3074 --- /dev/null +++ b/examples/dependent-project/src/main.ts @@ -0,0 +1,27 @@ +/** + * @license + * Copyright 2016 Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import {makeDefaultViewer} from 'neuroglancer/default_viewer'; +import {makeDefaultKeyBindings} from 'neuroglancer/default_key_bindings'; +import {navigateToOrigin} from 'my-neuroglancer-project/navigate_to_origin'; +import {makeExtraKeyBindings} from 'my-neuroglancer-project/extra_key_bindings'; + +window.addEventListener('DOMContentLoaded', () => { + let viewer = (window)['viewer'] = makeDefaultViewer(); + makeDefaultKeyBindings(viewer.keyMap); + makeExtraKeyBindings(viewer.keyMap); + viewer.keyCommands.set('navigate-to-origin', navigateToOrigin); +}); diff --git a/examples/dependent-project/src/my-neuroglancer-project/extra_key_bindings.ts b/examples/dependent-project/src/my-neuroglancer-project/extra_key_bindings.ts new file mode 100644 index 0000000000..ac71bc0d9e --- /dev/null +++ b/examples/dependent-project/src/my-neuroglancer-project/extra_key_bindings.ts @@ -0,0 +1,21 @@ +/** + * @license + * Copyright 2016 Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import {KeySequenceMap} from 'neuroglancer/util/keyboard_shortcut_handler'; + +export function makeExtraKeyBindings(keyMap: KeySequenceMap) { + keyMap.bind('keyo', 'navigate-to-origin'); +} diff --git a/examples/dependent-project/src/my-neuroglancer-project/navigate_to_origin.ts b/examples/dependent-project/src/my-neuroglancer-project/navigate_to_origin.ts new file mode 100644 index 0000000000..89f046ad12 --- /dev/null +++ b/examples/dependent-project/src/my-neuroglancer-project/navigate_to_origin.ts @@ -0,0 +1,25 @@ +/** + * @license + * Copyright 2016 Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import {kZeroVec} from 'neuroglancer/util/geom'; +import {Viewer} from 'neuroglancer/viewer'; + +export function navigateToOrigin(this: Viewer) { + let {position} = this.navigationState.pose; + if (position.valid) { + position.setVoxelCoordinates(kZeroVec); + } +} diff --git a/examples/dependent-project/third_party/neuroglancer b/examples/dependent-project/third_party/neuroglancer new file mode 120000 index 0000000000..be2958a384 --- /dev/null +++ b/examples/dependent-project/third_party/neuroglancer @@ -0,0 +1 @@ +../node_modules/neuroglancer/src/neuroglancer \ No newline at end of file diff --git a/examples/dependent-project/tsconfig.json b/examples/dependent-project/tsconfig.json new file mode 100644 index 0000000000..a749390ba7 --- /dev/null +++ b/examples/dependent-project/tsconfig.json @@ -0,0 +1,23 @@ +{ + "compilerOptions": { + "noImplicitAny": true, + "noImplicitReturns": true, + "noImplicitThis": true, + "preserveConstEnums": true, + "strictNullChecks": false, + "sourceMap": true, + "module": "commonjs", + "target": "ES2015", + "newLine": "LF", + "baseUrl": ".", + "paths": { + "*": ["*"], + "neuroglancer/*": ["third_party/neuroglancer/*"], + "my-neuroglancer-project/*": ["src/my-neuroglancer-project/*"] + } + }, + "exclude": [ + "node_modules", + "dist" + ] +} diff --git a/examples/dependent-project/tslint.json b/examples/dependent-project/tslint.json new file mode 100644 index 0000000000..1669edc18e --- /dev/null +++ b/examples/dependent-project/tslint.json @@ -0,0 +1,89 @@ +{ + "rulesDirectory": "node_modules/tslint-eslint-rules/dist/rules", + "rules": { + "align": [ + true, + "parameters", + "statements" + ], + "class-name": true, + "comment-format": [ + true, + "check-space" + ], + "eofline": [ + true + ], + "indent": [ + true, + "spaces" + ], + "jsdoc-format": true, + "no-duplicate-key": true, + "no-duplicate-variable": true, + "no-eval": true, + "no-internal-module": true, + "no-trailing-whitespace": true, + "no-unused-variable": true, + "no-var-keyword": false, + "one-line": [ + true, + "check-open-brace", + "check-whitespace" + ], + "quotemark": [ + true, + "single" + ], + "radix": true, + "semicolon": [ + true, + "always" + ], + "triple-equals": [ + true, + "allow-null-check" + ], + "typedef-whitespace": [ + true, + { + "call-signature": "nospace", + "index-signature": "nospace", + "parameter": "nospace", + "property-declaration": "nospace", + "variable-declaration": "nospace" + } + ], + "variable-name": [ + true, + "ban-keywords" + ], + "whitespace": [ + true, + "check-branch", + "check-decl", + "check-module", + "check-operator", + "check-separator", + "check-type" + ], + "no-conditional-assignment": true, + "no-duplicate-key": true, + "no-duplicate-case": true, + "no-empty-character-class": true, + "no-extra-boolean-cast": true, + "no-inner-declarations": [ + true, + "both" + ], + "no-invalid-regexp": true, + "no-irregular-whitespace": true, + "no-unexpected-multiline": true, + "no-unreachable": true, + "use-isnan": true, + "valid-typeof": true, + "curly": true, + "radix": true, + "no-shadowed-variable": true + } +} diff --git a/examples/dependent-project/typings/index.d.ts b/examples/dependent-project/typings/index.d.ts new file mode 100644 index 0000000000..2452393330 --- /dev/null +++ b/examples/dependent-project/typings/index.d.ts @@ -0,0 +1 @@ +/// diff --git a/tsconfig.json b/tsconfig.json index 77dd3ba528..20c6646487 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -19,6 +19,7 @@ "node_modules", "dist", "third_party/typings_sources", - "templates" + "templates", + "examples" ] }