Skip to content

Commit

Permalink
Initial commit of web-client-ui to it's own repository
Browse files Browse the repository at this point in the history
  • Loading branch information
mofojed committed Apr 26, 2021
0 parents commit 0e45148
Show file tree
Hide file tree
Showing 792 changed files with 201,520 additions and 0 deletions.
6 changes: 6 additions & 0 deletions .eslintrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"root": true,
"extends": [
"@deephaven/eslint-config"
]
}
39 changes: 39 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# See https://help.github.com/ignore-files/ for more about ignoring files.

# dependencies
/node_modules

# testing
/coverage

# production
/build
/dist

# misc
.vscode
.DS_Store
.env.local
.env.development.local
.env.test.local
.env.production.local
.project
.settings/
.eslintcache
.stylelintcache
lerna-debug.log
Lerna-Profile-*.json

/public/vs

npm-debug.log*
yarn-debug.log*
yarn-error.log*

src/**/*.css

cypress/screenshots
cypress/videos
cypress.env.json

tsconfig.tsbuildinfo
1 change: 1 addition & 0 deletions .npmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
@deephaven:registry=https://npm.pkg.github.com/
13 changes: 13 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
Copyright 2021 Deephaven Data Labs LLC

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.
32 changes: 32 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# Web Javascript packages

We're using a monorepo to manage our packages, as it becomes cumbersome to manage the overhead of multiple repos with how we wish to develop the Enterprise UI, while maintaining a separate OSS Code Studio solution. Using `lerna` to manage all of our packages in one repo simplifies the process.

## Getting Started

We are still using node 14.x and npm 6.x. If you are [using nvm](https://github.com/nvm-sh/nvm#installing-and-updating), run `nvm install lts/fermium` to get the latest 14.x/6.x versions. Otherwise, download from the [node homepage](https://nodejs.org/en/download/).

- `npm install` : Install all dependencies and automatically bootstrap packages
- `npm start`: Start building all packages and watching them (when possible). Use when you're developing, and your changes will be picked up automatically.
- `npm test`: Start running tests in all packages and watching (when possible). Use when you're developing, and any breaking changes will be printed out automatically.
- `npm run build`: Create a production build of all packages. Mainly used by CI when packaging up a production version of the app.
- `npm run sync-version`: Update the version of all packages to match `DEEPHAVEN_VERSION`. Used when updating/tagging new versions. It does not commit the changes.
- `npm run publish`: Publish the current versions of the packages that have not yet been published. If all packages with the current version have already been published, does nothing. Should be done after doing an `npm sync-version` and committing/tagging the release.

## Creating a New Package

Depending on what your package is, there are a couple of different templates that may be appropriate

### Application package

A standalone application with it's own entry point. Recommend using the [create-react-app template](https://github.com/facebook/create-react-app).

### Component/library package

Component template is located in `examples/component-template`. Use that template when making new component packages/libraries.

## Browser Support

Support is best for [Google Chrome](https://www.google.com/intl/en_ca/chrome/) and Chromium based browsers (such as [Microsoft Edge based on Chromium](https://www.microsoft.com/en-us/edge)). We try and maintain compatibility with [Mozilla Firefox](https://www.mozilla.org/en-CA/firefox/new/) and [Apple Safari](https://www.apple.com/ca/safari/) as well.

If you encounter an issue specific to a browser, check that your browser is up to date, then check issues labeled with [firefox](https://github.com/deephaven/core/labels/firefox) or [safari](https://github.com/deephaven/core/labels/safari) for a list of known browser compatibility issues before reporting the issue.
9 changes: 9 additions & 0 deletions babel.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
module.exports = {
presets: ['@deephaven/babel-preset'],
ignore: [
/\.test.(tsx?|jsx?)$/,
/\.stories.(tsx?|jsx?|mdx?)$/,
'**/__mocks__/*',
'**/*.scss',
],
};
78 changes: 78 additions & 0 deletions client-ui.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
plugins {
id 'com.bmuschko.docker-remote-api'
}

import com.bmuschko.gradle.docker.tasks.container.DockerCopyFileFromContainer
import com.bmuschko.gradle.docker.tasks.container.DockerCreateContainer
import com.bmuschko.gradle.docker.tasks.container.DockerRemoveContainer
import com.bmuschko.gradle.docker.tasks.image.DockerBuildImage

def syncSourcesLocation = "${buildDir}/src"

task syncSources(type: Sync) {
from "${projectDir}"
into syncSourcesLocation
// Note: we are explicitly choosing to sync the clean sources into a build directory to ensure
// that the context we use for caching the dockerBuild task is correct and has as minimal
// surface area as possible. Otherwise, web devs who like to build using npm locally will be
// creating a lot of extra noise that will cause dockerBuild task to run much slower than it
// could otherwise.

// Unfortunately, there doesn't seem to be a good / universal way to exclude the patterns from
// our existing .dockerignore.
exclude "**/node_modules"
exclude "**/dist"
exclude "**/build"
}

task dockerTest(type: DockerBuildImage) {
dependsOn syncSources
onlyIf { TestTools.shouldRunTests(project) }
inputDir.set(file(syncSourcesLocation))
target.set('test')
}

task dockerBuild(type: DockerBuildImage) {
dependsOn syncSources
inputDir.set(file(syncSourcesLocation))
target.set('build')
//buildArgs.put('DEEPHAVEN_VERSION', "${project.version}")
images.add('deephaven/iriside')
}

def dockerContainerName = "client-ui-container-${UUID.randomUUID()}"
def dockerCopyLocation = "${buildDir}/iriside"

task dockerCreateContainer(type: DockerCreateContainer) {
dependsOn dockerBuild
targetImageId dockerBuild.getImageId()
containerName.set(dockerContainerName)
}

task dockerRemoveContainer(type: DockerRemoveContainer) {
dependsOn dockerCreateContainer
targetContainerId dockerCreateContainer.getContainerId()
}

task ideClient(type: DockerCopyFileFromContainer) {
// note: we could try to be smarter and cache these create/remove tasks
dependsOn dockerCreateContainer
finalizedBy dockerRemoveContainer

inputs.property("imageId", dockerBuild.imageId)
outputs.dir(dockerCopyLocation)

targetContainerId dockerCreateContainer.getContainerId()

remotePath.set('/usr/src/app/packages/app/build')
hostPath.set(dockerCopyLocation)

doFirst {
// we must manually delete this first, since docker cp will error if trying to overwrite
delete(dockerCopyLocation)
}
}

check.dependsOn dockerTest

(tasks.getByName('clean') as Delete).delete('node_modules')
35 changes: 35 additions & 0 deletions examples/component-template/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# See https://help.github.com/ignore-files/ for more about ignoring files.

# dependencies
/node_modules

# testing
/coverage

# production
/build
/dist

# misc
.vscode
.DS_Store
.env.local
.env.development.local
.env.test.local
.env.production.local
.project
.settings/
.eslintcache
.stylelintcache

/public/vs

npm-debug.log*
yarn-debug.log*
yarn-error.log*

src/**/*.css

cypress/screenshots
cypress/videos
cypress.env.json
10 changes: 10 additions & 0 deletions examples/component-template/.storybook/main.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
module.exports = {
"stories": [
"../src/**/*.stories.mdx",
"../src/**/*.stories.@(js|jsx|ts|tsx)"
],
"addons": [
"@storybook/addon-links",
"@storybook/addon-essentials"
]
}
10 changes: 10 additions & 0 deletions examples/component-template/.storybook/preview.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@

export const parameters = {
actions: { argTypesRegex: "^on[A-Z].*" },
controls: {
matchers: {
color: /(background|color)$/i,
date: /Date$/,
},
},
}
1 change: 1 addition & 0 deletions examples/component-template/LICENSE.md
78 changes: 78 additions & 0 deletions examples/component-template/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
# @deephaven/component-template

This is an example which is setup to build components using Typescript, React, and Sass with Jest for testing and Storybook for isolated component development. Plain Javascript is also allowed, but for new components Typescript is preferred.

## Usage

1. Copy this folder into a new folder within the `packages` directory.
1. Open `package.json` in your new directory and give your package a new name. Lerna will ignore any packages with the name `@deephaven/component-template`
1. In the root of all the packages, run `npm bootstrap`. This will use lerna to install dependencies and symlink our packages together.
1. Add your package to the Dockerfile at the root of these packages. You will need to add lines to copy the appropriate files in all sections where there are several copy commands.

## Consuming the Component

The component template outputs an ES6 Module for consumption. If the component uses CSS, then using `import style.scss` will work just fine within the component.

To use the component, import it from the package such as `import { Example } from '@deephaven/component-template';`.
The way this template is configured, you MUST have some sort of bundler which handles CSS imports if the component uses Sass/CSS.

This mostly stems from the author of Webpack saying you shouldn't really nest Webpack bundles (consume a bundle then create another bundle). Check [here](https://github.com/webpack/webpack/issues/11277#issuecomment-670850832) for their comments. Also we don't have any plans for releasing the components as UMD/AMD/etc. and only as ESModules, so Webpack isn't necessary at the component level.

## Component Entry Point

The defualt entry point is `src/index.ts`. The entry point should serve as a collection of everything you want to expose from the component. It will likely contain re-exports like `export { default as Something } from './Something'`. If you need a different entry point (such as `.js` instead), change the `source` property in `package.json`.

## Build

The build step will transpile TS to JS (using Babel), generate type declarations (using TSC), compile Sass to CSS (using dart-sass), and update .scss imports to import .css files (using Babel). Everything will be put in the `dist` folder. The babel config is located at the root of the web client-ui packages. You can extend/override parts of it by creating a `.babelrc`

All JS/TS/JSX/TSX files you want in the output MUST be in `./src` since it is set as the `rootDir` in `tsconfig.json`

If you need another type of file copied, you will need to add it to the build process (Babel can be used with `--copy-files --no-copy-ignored` which should work since it ignores all the test/sass/storybook files)

If for some reason you need to build somewhere that isn't `dist`, you must update `tsconfig.json` and `package.json` to replace everywhere that `dist` is used with whatever you decide to build with.

The reason we use Babel and TSC is Babel doesn't actually type check TypeScript. TSC is set to emit declarations only.

## Start

`npm start` will run watch for changes to TS, JS, JSX, TSX, and SCSS files. On change they should be recompiled automatically and placed in the `dist` folder for the consuming app to detect and rebuild.

## Test

`npm test` will run Jest tests in watch mode. There are tests which run ESLint and Stylelint on all applicable files already included in `src/test`

## Linting

ESLint, Prettier, and Stylelint configs are all set at the root level of the web folder in the monorepo. If you need to override some rules or add additional rules, add them to their proper config file or `package.json` to cascade with the existing rules. See more for [ESLint](https://eslint.org/docs/user-guide/configuring/configuration-files#cascading-and-hierarchy), [Prettier](https://prettier.io/docs/en/configuration.html), and [Stylelint](https://stylelint.io/user-guide/configure)

You can add an `.eslintignore` file if needed.

## Storybook

You can use [Storybook](https://storybook.js.org/) to isolate your component for development. Just use `npm run storybook` to start a Storybook server for this component.

Storybook is setup with a default config in this template. Any `.stories.(jsx?|tsx?|mdx)` file should be picked up by Storybook and ignored by the build process.

## Best Practices

### Removing Unused Dependencies

React and react-dom are listed as peer dependencies. If your component doesn't need either, then remove them from peer and dev dependencies (and `@types/react`).

If not using sass, you can remove the dev dependency for sass and also remove the sass targeted scripts such as `build:sass` and `watch:sass`

`@testing-library/react` is a react component testing library. We currently use `enzyme` in several packages. Or you may not need this at all.

`gh-pages` is currently listed but not used by any scripts in this template.

### PropTypes

While prop-types is only truly needed for JS components, you should still keep and use the package for TS components.
It is unfortunately redundant when you have types in TS, but using `Component.propTypes` will keep it around for JS and give prop type errors in the browser.

If `Component.propTypes` is omitted in TS, it is still possible to pass the linter tests, but any consumption of the component by JS won't get TS type hints or browser prop type errors. This could easily lead to bugs when consuming the component in JS.

# Legal Notices

Deephaven Data Labs and any contributors grant you a license to the content of this repository under the Deephaven License, see the [LICENSE](LICENSE.md) file.
13 changes: 13 additions & 0 deletions examples/component-template/jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
export default {
transform: {
'.(ts|tsx|js|jsx)': 'ts-jest',
},
roots: ['./'],
testRegex: '(/__tests__/.*|\\.(test|spec))\\.(ts|tsx|js|jsx)$', // Everything in __tests__ or every .test|spec.ts|tsx|js
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json'],
moduleNameMapper: {
'\\.(css|less|scss|sass)$': 'identity-obj-proxy',
'\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$':
'<rootDir>/src/__mocks__/fileMock.js',
},
};
Loading

0 comments on commit 0e45148

Please sign in to comment.