Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: @talend/scripts module #1098

Merged
merged 18 commits into from
Feb 28, 2018
Merged
Show file tree
Hide file tree
Changes from 13 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
132 changes: 132 additions & 0 deletions packages/scripts/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
# Talend Scripts

## Description

This project, inspired by react-scripts and kcd-scripts, aims to abstract all tools and configuration from your project.
For now there are 3 goals :
* build and dev-serve: based on webpack
* lint: based on eslint
* test: based on jest and enzyme

## How to use

### Default usage

1. Add @talend/scripts as dev dependency.
```
Copy link
Contributor

Choose a reason for hiding this comment

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

You can use shell or bash here

yarn add --dev @talend/scripts
```

2. This is the only tool you'll need. You can remove all the devDependencies related to the 3 goals (build/test/lint).

3. Define the npm scripts
```json
{
"start": "talend-scripts-start",
"prepublish": "talend-scripts-build",
"test": "talend-scripts-test",
"lint": "talend-scripts-lint"
}
```

4. You're good to go

### Customization

Unlike react-scripts, we enable customisation. To start to customize it, just add a `talend-scripts.json` in your project root folder.

```json
{
"preset" : "talend",
"webpack": {
"config": {
"development": "./webpack.config.dev.js",
"production": "./webpack.config.prod.js"
}
},
"my-preset-other-configuration": {}
}
```

| Option | Description |
|---|---|
| preset | Default: `talend` We support presets. Please refer to the next section for more information. |
| webpack.config.developement | User custom webpack configuration in dev mode. It will be merged with preset default webpack configuration. With that, user can add/override the configuration. |
| webpack.config.production | Same as previous one, but for production mode. |
| other | This json object is available for the preset you use. This is the entry point to set the presets specific variables. It allows the preset to set some customisation points, instead of redefining a whole preset for some specificities. Refers to your preset documentation. |

## Presets

@Talend/scripts allows to define the webpack/linter/test configuration. Those are called presets.

### How to create

A preset is a node module `talend-scripts-preset-${presetName}`. It exports 3 functions

```javascript
module.exports = {
getWebpackConfiguration(presetApi) {},
getJestConfiguration(presetApi) {}, // TODO
getEslintConfiguration(presetApi) {} // TODO
}
```

The preset api contains the run mode and utility functions

```javascript
const { mode, getUserConfig } = presetApi;
```

| Preset api | Description |
|---|---|
| mode | The run mode : `development` or `production` |
| getUserConfig(path: array or string, defaultValue: any) | User configuration getter. They are defined in the `talend-scrips.json` file. It uses lodash.get under the hood, the object path can be an array of keys of a dot-separated string. |

### How to use

1. Install the preset

```
yarn add --dev talend-scripts-preset-${presetName}
```

2. Update the preset in talend-scripts.json

```
{
"preset": ${presetName}
}
```

3. Add any preset variables in talend-scripts.json, following your preset documentation.

### Preset talend configuration

```json
{
"preset": "talend",
"html": {
"title": "Talend Data Preparation"
},
"sass": {
"data": {
"$brand-primary": "#4F93A7",
"$brand-primary-t7": "#00A1B3",
"$brand-secondary-t7": "#168AA6"
}
},
"webpack": {
"config": {
"development": "./webpack.config.dev.js",
"production": "./webpack.config.prod.js"
},
"api-url": "http://localhost:3030"
}
}
```

| Preset variable | Description |
|---|---|
| html.title | The title to display on the browser tab. |
| sass.data | Define a set of sass variables to customise @talend/theme. |
| webpack.api-url | Default: `http://localhost`. The preset adds a proxy to `/api` urls. |
28 changes: 28 additions & 0 deletions packages/scripts/config/webpack.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
const mergeWith = require('lodash.mergeWith');
const { getAbsolutePath, getPreset, createUserConfigGetter } = require('../scripts/utils');
const getUserConfig = createUserConfigGetter();

const mode = process.env.TALEND_MODE || 'production';
const presetName = getUserConfig(['preset'], 'talend');
const preset = getPreset(presetName);

// Preset default configuration file
let webpackConfigurations = [];
webpackConfigurations = webpackConfigurations.concat(
preset.getWebpackConfiguration({ mode, getUserConfig })
);

// User configuration file
const userConfigPath = getUserConfig(['webpack', 'config', mode]);
if (userConfigPath) {
const userConfigAbsolutePath = getAbsolutePath(userConfigPath);
console.log(`Merge ${mode} webpack config with custom one (${userConfigAbsolutePath})`);
webpackConfigurations.push(require(userConfigAbsolutePath));
}

// Merge all configuration. User config can override preset ones,
module.exports = mergeWith({}, ...webpackConfigurations, function customizer(objValue, srcValue) {
if (Array.isArray(objValue)) {
return objValue.concat(srcValue);
}
});
41 changes: 41 additions & 0 deletions packages/scripts/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
{
"name": "@talend/scripts",
"version": "0.1.0",
"bin": {
"talend-scripts-start": "./scripts/start.js",
"talend-scripts-build": "./scripts/build.js"
},
"dependencies": {
"autoprefixer": "^7.1.4",
"babel-cli": "6.26.0",
"babel-core": "6.26.0",
"babel-loader": "7.1.2",
"babel-plugin-transform-class-properties": "6.24.1",
"babel-plugin-transform-export-extensions": "6.22.0",
"babel-plugin-transform-object-assign": "6.22.0",
"babel-plugin-transform-object-rest-spread": "6.26.0",
"babel-polyfill": "6.26.0",
"babel-preset-env": "1.6.0",
"babel-preset-react": "6.24.1",
"copy-webpack-plugin": "4.1.1",
"cross-spawn": "^6.0.4",
"css-loader": "0.28.7",
"extract-text-webpack-plugin": "3.0.2",
"file-loader": "1.1.5",
"html-webpack-plugin": "2.28.0",
"lodash.get": "^4.4.2",
"lodash.mergewith": "^4.6.1",
"node-sass": "4.7.2",
"postcss-loader": "2.0.8",
"resolve-url-loader": "^2.2.1",
"rimraf": "^2.6.2",
"sass-loader": "6.0.6",
"url-loader": "0.6.2",
"webpack": "3.8.1",
"webpack-cli": "^2.0.9",
"webpack-dev-server": "2.9.3",
"whatwg-fetch": "2.0.3",
"which": "^1.3.0",
"yargs-parser": "^9.0.2"
}
}
25 changes: 25 additions & 0 deletions packages/scripts/preset/config/.babelrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
"presets": [
[
"env",
{
"targets": {
"ie": 11,
"browsers": [
"last 2 versions"
]
}
}
],
"react"
],
"ignore": [
"**/**/*.css"
],
"plugins": [
"transform-class-properties",
"transform-export-extensions",
"transform-object-assign",
"transform-object-rest-spread"
]
}
26 changes: 26 additions & 0 deletions packages/scripts/preset/config/webpack.config.dev.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
const webpack = require('webpack');

module.exports = ({ getUserConfig }) => ({
output: {
path: `${process.cwd()}/build`,
},
watchOptions: {
aggregateTimeout: 300,
poll: 1000,
},
devServer: {
port: 3000,
proxy: {
'/api': {
target: getUserConfig(['webpack', 'api-url'], 'http://localhost'),
changeOrigin: true,
secure: false,
},
},
historyApiFallback: true,
},
devtool: 'inline-source-map',
plugins: [
new webpack.DefinePlugin({ 'process.env.NODE_ENV': JSON.stringify('development') }),
],
});
102 changes: 102 additions & 0 deletions packages/scripts/preset/config/webpack.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
const autoprefixer = require('autoprefixer');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');

const babelrc = require('./.babelrc.json');
const extractCSS = new ExtractTextPlugin({ filename: '[name]-[hash].css' });

function getSassData(getUserConfig) {
const sassData = '@import \'~@talend/bootstrap-theme/src/theme/guidelines\';';
const userSassData = getUserConfig(['sass', 'data']);
if (userSassData) {
const adaptedUserSassData = Object.keys(userSassData)
.map(key => (`${key}: ${userSassData[key]};`))
.join('\n');
return `${adaptedUserSassData}\n${sassData}`;
}
return sassData;
}

function getCommonStyleLoaders(enableModules) {
let cssOptions = {};
if (enableModules) {
cssOptions = {
sourceMap: true,
modules: true,
importLoaders: 1,
localIdentName: '[name]__[local]___[hash:base64:5]',
};
}
return [
{ loader: 'css-loader', options: cssOptions },
{
loader: 'postcss-loader',
options: { sourceMap: true, plugins: () => [autoprefixer({ browsers: ['last 2 versions'] })] },
},
{ loader: 'resolve-url-loader' },
];
}

function getSassLoaders(enableModules, sassData) {
return getCommonStyleLoaders(enableModules).concat({
loader: 'sass-loader',
options: { sourceMap: true, data: sassData },
});
}

module.exports = ({ getUserConfig }) => {
const sassData = getSassData(getUserConfig);

return {
entry: ['babel-polyfill', 'whatwg-fetch', `${process.cwd()}/src/app/index.js`],
output: {
path: `${process.cwd()}/dist`,
publicPath: '/',
filename: '[name]-[hash].js',
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: babelrc,
},
},
{
test: /\.css$/,
use: extractCSS.extract(getCommonStyleLoaders()),
exclude: /@talend/,
},
{
test: /\.scss$/,
use: extractCSS.extract(getSassLoaders(false, sassData)),
include: /bootstrap-theme/,
},
{
test: /\.scss$/,
use: extractCSS.extract(getSassLoaders(true, sassData)),
exclude: /bootstrap-theme/,
},
{
test: /\.woff(2)?(\?v=\d+\.\d+\.\d+)?$/,
loader: 'url-loader',
options: { name: './fonts/[name].[ext]', limit: 50000, mimetype: 'application/font-woff' },
},
],
},
plugins: [
extractCSS,
new HtmlWebpackPlugin({
filename: './index.html',
template: `${process.cwd()}/src/app/index.html`,
title: getUserConfig(['html', 'title']),
}),
new CopyWebpackPlugin([
{ from: 'src/assets' },
]),
],
};
};
17 changes: 17 additions & 0 deletions packages/scripts/preset/config/webpack.config.prod.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
const webpack = require('webpack');

module.exports = () => ({
plugins: [
new webpack.optimize.UglifyJsPlugin({
compress: {
warnings: false,
},
comments: false,
mangle: true,
minimize: true,
}),
new webpack.DefinePlugin({
'process.env.NODE_ENV': JSON.stringify('production'),
}),
],
});
15 changes: 15 additions & 0 deletions packages/scripts/preset/preset-talend-webpack.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
const getCommonWebpackConfig = require('./config/webpack.config');
const getDevWebpackConfig = require('./config/webpack.config.dev');
const getProdWebpackConfig = require('./config/webpack.config.prod');

module.exports = function getWebpackConfiguration(presetApi) {
const webpackConfigurations = [getCommonWebpackConfig(presetApi)];

if (presetApi.mode === 'development') {
webpackConfigurations.push(getDevWebpackConfig(presetApi));
} else if (presetApi.mode === 'production') {
webpackConfigurations.push(getProdWebpackConfig(presetApi));
}

return webpackConfigurations;
};
5 changes: 5 additions & 0 deletions packages/scripts/preset/preset-talend.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
const getWebpackConfiguration = require('./preset-talend-webpack');

module.exports = {
getWebpackConfiguration,
};
Loading