Skip to content
This repository has been archived by the owner on Aug 30, 2019. It is now read-only.

[WIP] Implementation of issue #6's proposal #7

Merged
merged 1 commit into from Feb 15, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
6 changes: 4 additions & 2 deletions .eslintrc
Expand Up @@ -13,11 +13,13 @@
],
"globals": {
"__base": true,
"describe": true,
"it": true,
"assert": true,
"beforeEach": true,
"describe": true,
"enzyme": true,
"expect": true,
"it": true,
"jest": true,
"React": true,
"ReactDOM": true
},
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Expand Up @@ -6,3 +6,4 @@ node_modules/
styleguide/
themes/theme.scss
.DS_Store
wallaby.js
69 changes: 63 additions & 6 deletions README.md
Expand Up @@ -7,10 +7,66 @@ Travix UI Components' repository.
## UI-Kit
### How to install and setup
- `npm i travix-ui-kit -S` install as a dependency
- add npm script `build` with value `cd node_modules/travix-ui-kit/ && npm run build && cd ../..` to your `package.json`

### How to use
#### JS
### Usage

#### CLI

The UI Kit comes with a CLI tool to help you build your UI bundles (JS and CSS).

To see the options available:

```bash
$ node_modules/.bin/travix-ui-kit -h

Usage: travix-ui-kit [options]

Options:

-h, --help output usage information
-V, --version output the version number
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is V capital?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It comes from commander: tj/commander.js#560

Nevertheless it is also more common to do -v to add verbosity on node CLI tools. Still, it is possible to provide an override of the help I think.

-c, --css-dir <directory> Destination directory of the ui-kit.css
-j, --js-dir <directory> Destination directory of the ui-kit.js
-t, --theme-file <path> Path to a theme file to override default UI Kit styles
-w, --watch Enables file-watcher functionality
```

For example, if we want to generate our UI Bundles, with the default styling, on `./js/` and `./css/` folders,
we do:

```bash
$ node_modules/.bin/travix-ui-kit -j ./js/ -c ./css/
```

If we want to pass our own YAML file for styling, we also can do it:

```bash
$ node_modules/.bin/travix-ui-kit -j ./js/ -c ./css/ -t ./myDefaultStyle.yml
```

And for development purposes, we tend to want to watch for changes on the files.
That's possible too:

```bash
$ node_modules/.bin/travix-ui-kit -j ./js/ -c ./css/ -t ./myDefaultStyle.yml -w
```


For simplicity purposes we suggest to add a task/script to your `package.json`,
which simplifies the usage of the CLI. E.g.:

```js
{
"scripts": {
"build:ui": "travix-ui-kit -j ./js/ -c ./css/ -t ./myDefaultStyle.yml",
"build:ui-watch": "travix-ui-kit -j ./js/ -c ./css/ -t ./myDefaultStyle.yml -w",
}
}
```

#### The components

##### JS
```javascript
const Button = require('travix-ui-kit').Button;
// or
Expand All @@ -22,14 +78,16 @@ Travix UI Components' repository.
);
}
```
#### CSS
##### CSS
use file `node_modules/travix-ui-kit/dist/bundle.css`
- you can create an alias in your webpack plugin
- or inject it in your page current styles bundle
- or copy to public folder and add as separate style file with `<link>`

**Warning**: Directly using file `components/index.scss` not recommended. We're not promising that we will use SCSS in future or will keep file's structure

---

## Living style guide

### Before installation
Expand Down Expand Up @@ -57,8 +115,7 @@ use file `node_modules/travix-ui-kit/dist/bundle.css`
#### Start developing

- `npm run build:watch` to build the themes, styles and javascript on each file change
- `npm run build-theme:watch` to build the themes on each theme change
- `THEME_PATH=/some/path/to/theme.yaml npm run build` to pass other than default theme. Theme must be a valid yaml file
- `npm run build:watch -- -t "./path/to/my/theme.yml"` to build using a custom theme (also can use the other options as well).
- `npm run styleguide-server` to run web service with livingstyle guide and review changes

#### Testing
Expand Down
22 changes: 0 additions & 22 deletions bin/build-theme.js

This file was deleted.

28 changes: 28 additions & 0 deletions builder/builder.js
@@ -0,0 +1,28 @@
const getStylesAndSaveTheme = require('./getStylesAndSaveTheme');
const runWebpackAndCopyFilesToFinalDestination = require('./runWebpackAndCopyFilesToFinalDestination');
const webpackConfig = require('./webpack.config');

const webpackNodeEnv = {
'process.env.NODE_ENV': process.env.NODE_ENV || 'development',
};

/**
* Triggers the build process.
*
* @module builder
* @param {String} cssDir Destination folder for the ui-bundle.css
* @param {String} jsDir Destination folder for the ui-bundle.js
* @param {String} themeFile Path where a custom YAML w/ styles' definitions
* @param {Boolean} watch Flag to determine if it should run in 'watch' mode
* @return {Promise}
*/
module.exports = ({ cssDir, jsDir, themeFile, watch }) => {
return getStylesAndSaveTheme(themeFile, watch)
.then(runWebpackAndCopyFilesToFinalDestination({
webpackConfig,
webpackNodeEnv,
cssDir,
jsDir,
watch,
}));
};
34 changes: 34 additions & 0 deletions builder/copyToFinalDestination.js
@@ -0,0 +1,34 @@
const fs = require('fs');
const path = require('path');

/**
* Copies a given file from one path to another.
*
* @module copyToFinalDestination
* @param {String} originalPath Source path to be copied
* @param {String} finalPath Destination folder to copy the originalPath to.
* @return {Promise}
*/
module.exports = ({ originalPath, finalPath }) => new Promise((resolve, reject) => {
if (!finalPath) {
resolve();
return;
}

const copyTo = path.join(finalPath, path.basename(originalPath));
fs.readFile(originalPath, (readErr, content) => {
if (readErr) {
reject(readErr);
return;
}

fs.writeFile(copyTo, content, (writeErr) => {
if (writeErr) {
reject(writeErr);
return;
}

resolve();
});
});
});
24 changes: 24 additions & 0 deletions builder/generateThemeFile.js
@@ -0,0 +1,24 @@
const fs = require('fs');
const saveThemeScssFile = require('./saveThemeScssFile');
const themeBuilder = require('theme-builder');

/**
* Generates the themes/theme.scss file, based on a given YAML file.
*
* @module generateThemeFile
* @param {String} yamlFile File path to a YAML file with the styles' definitions.
* @return {Promise}
*/
module.exports = (yamlFile) => {
return new Promise((resolve, reject) => {
fs.readFile(yamlFile, { encoding: 'utf-8' }, (err, content) => {
if (err) {
reject(err);
return;
}

const themeChunks = themeBuilder(content, 'scss', { prefix: 'tx' });
resolve(themeChunks.join('\n'));
});
}).then(saveThemeScssFile);
};
25 changes: 25 additions & 0 deletions builder/getStylesAndSaveTheme.js
@@ -0,0 +1,25 @@
const fs = require('fs');
const path = require('path');
const generateThemeFile = require('./generateThemeFile');

/**
* Triggers the generation of the theme file (theme.scss)
* and handles the watch mode.
*
* @module getStylesAndSaveTheme
* @param {String} [themeFile] Path to a custom YAML file with styles' definitions.
* @param {Boolean} [isWatchEnabled] Flag that enables the 'watch mode' when true. Default: false.
* @return {Promise}
*/
module.exports = (themeFile, isWatchEnabled) => new Promise((resolve, reject) => {
const yamlFile = themeFile || path.join(__dirname, '..', 'themes', '_default.yaml');

if (isWatchEnabled) {
fs.watch(yamlFile, { persistent: true }, () => {
/** TODO: Do proper error handling on watch mode */
generateThemeFile(yamlFile).catch(reject);
});
}

generateThemeFile(yamlFile).then(resolve).catch(reject);
});
18 changes: 18 additions & 0 deletions builder/index.js
@@ -0,0 +1,18 @@
#!/usr/bin/env node

const program = require('commander');
const pkg = require('../package.json');
const builder = require('./builder');

program
.version(pkg.version)
.option('-c, --css-dir <directory>', 'Destination directory of the ui-kit.css')
.option('-j, --js-dir <directory>', 'Destination directory of the ui-kit.js')
.option('-t, --theme-file <path>', 'Path to a theme file to override default UI Kit styles')
.option('-w, --watch', 'Enables file-watcher functionality', false);

program.parse(process.argv);

builder(program)
.then(() => console.log('Done!'))
.catch(console.error);
38 changes: 38 additions & 0 deletions builder/runWebpackAndCopyFilesToFinalDestination.js
@@ -0,0 +1,38 @@
const copyToFinalDestination = require('./copyToFinalDestination');
const path = require('path');
const webpack = require('webpack');

/**
* @module runWebpackAndCopyFilesToFinaDestination
* @param {Object} options Object containing the configuration props.
* @param {String} options.cssDir Folder where to place the ui-bundle.css
* @param {String} options.jsDir Folder where to place the ui-bundle.js
* @param {String} options.watch Flag that enables the 'watch mode' on Webpack. Default: false
* @param {Object} options.webpackConfig Webpack configuration object
* @param {Object} options.webpackNodeEnv Webpack NODE_ENV configuration
* @return {Promise}
*/
module.exports = ({ cssDir, jsDir, watch, webpackConfig, webpackNodeEnv }) => new Promise((resolve, reject) => {
webpackConfig.plugins.push(new webpack.DefinePlugin(webpackNodeEnv));
webpackConfig.context = __dirname;

const runner = webpack(webpackConfig);
const runnerFn = watch ? runner.watch.bind(runner, {}) : runner.run.bind(runner);

runnerFn((err, stats) => {
if (err) {
reject(err);
return;
}

copyToFinalDestination({
finalPath: jsDir,
originalPath: path.join(webpackConfig.output.path, 'ui-bundle.js'),
}).then(() => copyToFinalDestination({
finalPath: cssDir,
originalPath: path.join(webpackConfig.output.path, 'ui-bundle.css'),
})).then(() => {
resolve(stats);
}).catch(reject);
});
});
18 changes: 18 additions & 0 deletions builder/saveThemeScssFile.js
@@ -0,0 +1,18 @@
const fs = require('fs');
const path = require('path');

/**
* @module saveThemeScssFile
* @param {String} themeScss SCSS content to be stored as themes/theme.scss
* @return {Promise}
*/
module.exports = themeScss => new Promise((resolve, reject) => {
fs.writeFile(path.join(__dirname, '..', 'themes', 'theme.scss'), themeScss, (err) => {
if (err) {
reject(err);
return;
}

resolve();
});
});
11 changes: 8 additions & 3 deletions webpack.config.js → builder/webpack.config.js
@@ -1,13 +1,18 @@
const autoprefixer = require('autoprefixer');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const path = require('path');

const outputDir = './dist/';
const outputDir = path.join(__dirname, '..', 'dist');

/**
* @module webpack.config
* @type {Object}
*/
module.exports = {
entry: {
dist: [
'./components/index.scss',
'./components/index.js',
'../components/index.scss',
'../components/index.js',
],
},

Expand Down
12 changes: 8 additions & 4 deletions package.json
Expand Up @@ -4,10 +4,10 @@
"description": "Travix UI kit",
"main": "lib/index.js",
"scripts": {
"build": "npm run build-theme && webpack && babel --copy-files ./components --out-dir lib --ignore *.scss,*.md",
"build:watch": "npm run build-theme:watch & webpack --watch& babel --copy-files ./components --out-dir lib --ignore *.scss,*.md -w",
"build-theme": "node bin/build-theme.js",
"build-theme:watch": "node bin/build-theme.js --watch",
"prebuild": "babel --copy-files ./components --out-dir lib --ignore *.scss,*.md &",
"build": "node ./builder",
"build:watch": "node ./builder -w",
"prebuild:watch": "babel --copy-files ./components --out-dir lib --ignore *.scss,*.md -w &",
"styleguide-server": "styleguidist server",
"styleguide-build": "styleguidist build",
"test": "jest -c ./tests/jest.config.json",
Expand All @@ -17,6 +17,9 @@
"lint": "eslint --color '{components,tests,utils,scripts}/**/*.js'",
"transpile": "npm run build"
},
"bin": {
"travix-ui-kit": "./builder/index.js"
},
"repository": {
"type": "git",
"url": "git@github.com:Travix-International/travix-ui-kit.git"
Expand Down Expand Up @@ -54,6 +57,7 @@
"babel-loader": "^6.2.5",
"babel-preset-travix": "^1.1.0",
"babel-register": "^6.16.3",
"commander": "^2.9.0",
"css-loader": "^0.26.1",
"extract-text-webpack-plugin": "^1.0.1",
"node-sass": "^4.3.0",
Expand Down