Skip to content

Commit

Permalink
feat: add initial build scripts (#2)
Browse files Browse the repository at this point in the history
  • Loading branch information
Adam Butterworth authored Sep 24, 2019
1 parent 82e77ec commit 5ec393a
Show file tree
Hide file tree
Showing 29 changed files with 20,655 additions and 3 deletions.
16 changes: 16 additions & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
const { createConfig } = require('./');

module.exports = createConfig('eslint', {
rules: {
'no-console': 'off',
'import/no-dynamic-require': 'off',
'global-require': 'off',
'no-template-curly-in-string': 'off',
},
"parserOptions": {
"ecmaVersion": 2017
},
"env": {
"es6": true
},
});
8 changes: 8 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
.DS_Store
.eslintcache
.idea
.vscode
coverage
dist
node_modules
npm-debug.log
14 changes: 14 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
language: node_js
node_js: 12
install:
- npm install
script:
- npm run lint
after_success:
- npx semantic-release
env:
global:
# GH_TOKEN
- secure: kuLoGeg37ASpPr6XEfADXKKlL/jpmnXX5gqhjJycQ+liogUQN+9NVzqeaPfGPTz9sY34F/dG7F1bR8BxGl1AxpqQsSwSD1lhCNF4j5K3bT6KIr04B1X5TDyaEXU40IP0nyrT0tFk3aaFP+mw6YHgg0KXNj/wuWqwwGY03roT31+E6RTDhlwuE443u4l6+ApdjmQP9Dmm0H3i220PtqU0RcNSXizs+kdlACfquwHHMjyhRFLG71++bKuV9YWrio16yDwjooKsqsW7faPeGVwDRPJvwVCyBjsZuR7hLkMOWIm1CB4xeX94jy2o8q7zGzjDxUyLYI3cliMLpsfcsPFZLpoNnh4NkeVLY9beZ0IdAAtkjm59mddGAQp630zLJSSzmKDTVDKLRIN0Ns+wslvmuzVb8LBSYa/hKyg1/qjl77IJT9Mz0Sbm2r+Wj9bviyXt4CguM7Qizpst0mDlxxN9D74iYvx6VQoLbOH5uy5kCXRYnSjZHlaOc2/GlNrXQ9eP/8PLam556R8IHvvzfFodeSAgxCwTMypkWBFf55b74OjT+Twf3e0UcjdSJeND7f8Rnk1pUOsnUUY0LeZS/CngPUhPVJmDUkHyoQupq1OMALjvGJBwKaQihp3DfqfUeFzRm3ajkpJKzx2VDxi6zWg08bidClD7JWd+x1mGYw3roQk=
# NPM_TOKEN
- secure: XkgAdCg2ZHbvxds1u7UPCvcRbRZRwn2wiokz+pkyoZd0IKLEhbImY4DaOgolJ/9NfeCqEqbDIexGy74JRJptgKe6MPmlZiDPj6azhkgI0HD+QLvvkntj3E+m0ssSlnbwb+dicea6Fxkk9JKNln8XcU0XEDo922Q55Mz4t07aYu7i3qhfSP/1oBYGsxd/IFmuR8fhvWT8hEEO0Lx0qAloXql5ECK01DeuUGsVUkY77mpyNwRUDWALWHe/y/stYcUwyu4pxjUQvyn3Rz4FrsrcbpIS3/4T5X4ImMyMwcRaFymRJwkBypjHeJPWsH5HZ5XLwED6o7YGAuVIoRDLOuJg3O6vxwNGqv7qDvm+r1C3Gj7GzfIIyXb+9lDWCifrWzY7v14Am/v0MZ7vbdrcjMXTXGVZ+2TVva9T1m6pz/mR+dNqVY765fn/iibLSuDKdAyR0QXoQoBp7awxbPpjN+gQSwwJpaCtgJHfOHl4+Jc47jt0OS0UQY/ilm+4Xvf2MUS4kZkp/y5iwBIoFjr1MBkkXDkD9WCENrwrNeFmbK7ijdI0nlE7ZvYdSaI9ohstNFKqhaZ0r16v7t3z8xP+nL0yqM+HWLyAp2f1WsTuTMpwAY4+b47ftD2msCWWpY09BcfxmAwl8KKHIVgwSA7p6xMYk/V7P4vzKlI+IpmEWC4Xgyc=
76 changes: 73 additions & 3 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,24 @@ frontend-build

|Build Status| |Codecov| |license|

This repository is under active development. The purpose of this package is to provide a common sense foundation and setup for frontend projects including:
The purpose of this package is to
provide a common sense foundation and setup for frontend projects including:

- linting (eslint)
- testing (jest)
- development server (webpack-dev-server)
- build (webpack)

This package can serve as a single dev dependency replacing a large number of dev and build dependencies. It aims to provide common sense defaults that should be good for most edX projects out of the box, but can extended or overridden where needed.
This package can serve as a single dev dependency replacing a large number of
dev and build dependencies. It aims to provide common sense defaults that
should be good for most edX projects out of the box, but can extended or
overridden where needed.

package.json::
Usage
-----

CLI commands are structured: ``fedx-scripts <targetScript> <options>``.
Example package.json::

{
"scripts": {
Expand All @@ -32,6 +40,68 @@ package.json::
}
}

Extending or Overriding Default Config
--------------------------------------

This package contains default configuration for each command it
offers (webpack, webpack-dev-server, babel, jest, eslint). If you
need to extend or modify the base configuration you can add your
own configuration files, either by extending frontend-build's
configuration files or supplying your own wholesale.

Method 1: Extend base config (babel.config.js)::

const { createConfig } = require('@edx/frontend-build');
module.exports = createConfig('babel', {
/* option overrides or extensions */
});

Method 2: Custom manipulations (babel.config.js)::

const { getBaseConfig } = require('@edx/frontend-build');
const config = getBaseConfig('babel');

/* Custom config manipulations */

module.exports = config;

Frontend build will look in the following locations for configuration
files.

- eslint: ``<project_root>/.eslintrc.js``
- jest: ``<project_root>/'jest.config.js``
- babel: ``<project_root>/'babel.config.js``
- webpack-prod: ``<project_root>/'webpack.prod.config.js``
- webpack-dev-server: ``<project_root>/'webpack.dev.config.js``

You may specify custom config file locations via the command
line if you prefer a different location. Example package.json::

{
"scripts": {
"build": "fedx-scripts webpack --config=./config/webpack.config.js",
...
}
}

Development
-----------

This project leverages the command line interface for webpack, jest, eslint, and babel.
Because of this, local development can be tricky. The easiest way to do local
development on this project is to put it inside a project where it will be used and
running `npm i -D ./frontend-build`. Most of the time this should put install
dependencies in the right location, but it's not fool proof. If you run into errors that
say something like "webpack: command not found" you have two options.

1. Delete the node_modules directories from the host project and this one and re-run
`npm i -D ./frontend-build` from the host project.

2. Pack this project and install it by running
`npm install $(npm pack ../frontend-build/ | tail -1)`. This should work every time but
you will need to run it every time you make changes to this project.


.. |Build Status| image:: https://api.travis-ci.org/edx/frontend-base.svg?branch=master
:target: https://travis-ci.org/edx/frontend-base
.. |Codecov| image:: https://img.shields.io/codecov/c/github/edx/frontend-base
Expand Down
19 changes: 19 additions & 0 deletions bin/fedx-scripts.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#!/usr/bin/env node

process.env.PROJECT_ROOT = process.cwd();

// args come in the format: node fedx-scripts <command> <options>
const args = process.argv.slice(2);
const command = args.shift();

switch (command) {
case 'babel':
case 'eslint':
case 'jest':
case 'webpack':
case 'webpack-dev-server':
require(`../scripts/${command}.js`)(args);
break;
default:
console.log(`fedx-scripts: The command ${command} is unsupported`);
}
34 changes: 34 additions & 0 deletions config/.eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
module.exports = {
"extends": "eslint-config-edx",
"parser": "babel-eslint",
"rules": {
"import/no-extraneous-dependencies": [
"error",
{
"devDependencies": [
"**/*.config.*",
"**/*.test.*",
"**/setupTest.js",
]
}
],
// https://github.com/evcohen/eslint-plugin-jsx-a11y/issues/340#issuecomment-338424908
"jsx-a11y/anchor-is-valid": [ "error", {
"components": [ "Link" ],
"specialLink": [ "to" ]
}],
"jsx-a11y/label-has-for": [ 2, {
"components": [ "label" ],
"required": {
"some": [ "nesting", "id" ]
},
"allowChildren": false
}]
},
"env": {
"jest": true
},
"globals": {
"newrelic": false
}
}
41 changes: 41 additions & 0 deletions config/babel.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
module.exports = {
presets: [
'@babel/preset-env',
'@babel/preset-react',
],
plugins: [
'@babel/plugin-proposal-object-rest-spread',
'@babel/plugin-proposal-class-properties',
'@babel/plugin-syntax-dynamic-import',
[
'transform-imports',
{
'@fortawesome/free-brands-svg-icons': {
transform: '@fortawesome/free-brands-svg-icons/${member}',
skipDefaultConversion: true,
},
'@fortawesome/free-regular-svg-icons': {
transform: '@fortawesome/free-regular-svg-icons/${member}',
skipDefaultConversion: true,
},
'@fortawesome/free-solid-svg-icons': {
transform: '@fortawesome/free-solid-svg-icons/${member}',
skipDefaultConversion: true,
},
},
],
],
env: {
i18n: {
plugins: [
[
'react-intl',
{
messagesDir: './temp/babel-plugin-react-intl',
moduleSourceName: '@edx/frontend-i18n',
},
],
],
},
},
};
35 changes: 35 additions & 0 deletions config/jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
const path = require('path');

const getProjectConfigFile = require('../lib/getProjectConfigFile');
const { PROJECT_ROOT } = require('../lib/paths');

module.exports = {
testURL: 'http://localhost/',
setupFiles: [
path.resolve(__dirname, 'jest/setupTest.js'),
],
rootDir: PROJECT_ROOT,
moduleNameMapper: {
'\\.svg': path.resolve(__dirname, 'jest/svgrMock.js'),
'\\.(jpg|jpeg|png|gif|eot|otf|webp|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$': path.resolve(__dirname, 'jest/fileMock.js'),
'\\.(css|scss)$': 'identity-obj-proxy',
},
collectCoverageFrom: [
'src/**/*.{js,jsx}',
],
coveragePathIgnorePatterns: [
'/node_modules/',
'setupTest.js',
],
transformIgnorePatterns: [
'/node_modules/(?!@edx)',
],
transform: {
'^.+\\.[t|j]sx?$': [
'babel-jest',
{
configFile: getProjectConfigFile('babel'),
},
],
},
};
1 change: 1 addition & 0 deletions config/jest/fileMock.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
module.exports = 'test-file-stub';
14 changes: 14 additions & 0 deletions config/jest/setupTest.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
const path = require('path');
const fs = require('fs');
const dotenv = require('dotenv');
require('babel-polyfill');

const { PROJECT_ROOT } = require('../../lib/paths');

const testEnvFile = path.resolve(PROJECT_ROOT, '.env.development');

if (fs.existsSync(testEnvFile)) {
dotenv.config({ path: testEnvFile });
} else {
console.log(`No .env.development file found at ${testEnvFile}. No env vars will be loaded.`);
}
1 change: 1 addition & 0 deletions config/jest/svgrMock.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
module.exports = { ReactComponent: 'IconMock' };
16 changes: 16 additions & 0 deletions config/webpack.common.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
const path = require('path');

const { PROJECT_ROOT } = require('../lib/paths');

module.exports = {
entry: {
app: path.resolve(PROJECT_ROOT, 'src/index'),
},
output: {
path: path.resolve(PROJECT_ROOT, 'dist'),
publicPath: '/',
},
resolve: {
extensions: ['.js', '.jsx'],
},
};
Loading

0 comments on commit 5ec393a

Please sign in to comment.