Skip to content

Instantly share code, notes, and snippets.

@gutchom
Last active October 26, 2017 23:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gutchom/20997bbe5290ecb62eeccb5cd85e4a80 to your computer and use it in GitHub Desktop.
Save gutchom/20997bbe5290ecb62eeccb5cd85e4a80 to your computer and use it in GitHub Desktop.
Config files for my front-end development environment
All files are MIT Licence.
const webpackConfig = require('./webpack.config')
module.exports = config => {
config.set({
basePath: './src/scripts',
frameworks: ['power-assert', 'mocha'],
browsers: ['ChromeHeadless'],
mime: {
'text/x-typescript': ['ts','tsx']
},
files: [
'test/**/*.test.+(ts|tsx)',
],
preprocessors: {
'app/**/*.+(ts|tsx)': ['webpack', 'sourcemap'],
'test/**/*.test.+(ts|tsx)': ['webpack', 'sourcemap'],
},
plugins: [
'karma-coverage',
'karma-mocha',
'karma-mocha-reporter',
'karma-power-assert',
'karma-chrome-launcher',
'karma-sourcemap-writer',
'karma-sourcemap-loader',
'karma-webpack',
],
port: 9876,
concurrency: Infinity,
singleRun: true,
reporters: ['mocha'],
mochaReporter: {
colors: true,
},
browserConsoleLogOptions: {
level: '',
terminal: true,
},
loggers: [
{ type: 'console'},
],
logLevel: config.LOG_INFO,
webpack: webpackConfig,
webpackMiddleware: {
stats: 'errors-only',
},
})
}
{
"name": "observe-2ch-client",
"version": "0.1.0",
"description": "UI for Observe 2ch Web",
"author": "gutchom",
"license": "MIT",
"homepage": "https://observe-2ch.gutchom.com",
"repository": {
"type": "git",
"url": "https://github.com/gutchom/observe-2ch-client"
},
"bugs": {
"url": "https://github.com/gutchom/observe-2ch-client/issues"
},
"engines": {
"node": "^8.*",
"npm": "^5.*"
},
"scripts": {
"start": "cross-env NODE_ENV=development run-p -s count server:** 'build:** -- -w'",
"test": "cross-env NODE_ENV=test karma start",
"testing": "npm t -- --auto-watch --no-single-run",
"build": "cross-env NODE_ENV=production run-s lint:** test clean build:** count",
"build:image": "cpx ./src/images/**/* ./public/img",
"build:style": "postcss ./src/styles/pages/**/*.css -b ./src/styles/pages -d ./public/css",
"build:script": "webpack --progress",
"lint": "run-p lint:**",
"lint:style": "stylelint --fix ./src/styles/**/*.css",
"lint:script": "tslint -p tsconfig.json --fix ./src/**/*.ts*",
"server:mock": "cross-env PORT=${OBSERVE_2CH_PORT-3000} nodemon -w ./server ./server",
"server:sync": "browser-sync start -b 'google chrome' -f ./public -p localhost:${OBSERVE_2CH_PORT-3000} --port ${OBSERVE_2CH_SYNC-3333}",
"clean": "rimraf ./public && mkdirp ./public/js ./public/css ./public/img",
"count": "TOTAL=$(find ./src -name '*.ts*' -o -name '*.css' | xargs wc -l | tail -1); printf '\\e[36m\n This project has\\e[35m %s lines\\e[36m of source code!\n\n\\e[m' ${TOTAL%total}"
},
"dependencies": {
"@tweenjs/tween.js": "^17.1.1",
"axios": "^0.17.0",
"eventemitter3": "^2.0.3",
"normalize.css": "^7.0.0",
"react": "^16.0.0",
"react-dom": "^16.0.0",
"url-search-params-polyfill": "^2.0.1"
},
"devDependencies": {
"@types/enzyme": "^3.1.1",
"@types/eventemitter3": "^2.0.2",
"@types/mocha": "^2.2.43",
"@types/node": "^8.0.47",
"@types/power-assert": "^1.4.29",
"@types/react": "^16.0.18",
"@types/react-dom": "^16.0.2",
"@types/sinon": "^2.3.7",
"@types/tween.js": "16.9.0",
"babel-core": "^6.26.0",
"babel-loader": "^7.1.2",
"babel-plugin-transform-class-properties": "^6.24.1",
"babel-plugin-transform-decorators-legacy": "^1.3.4",
"babel-plugin-transform-object-rest-spread": "^6.26.0",
"babel-preset-airbnb": "^2.4.0",
"babel-preset-env": "^1.6.1",
"babel-preset-power-assert": "^1.0.0",
"babel-preset-react": "^6.24.1",
"babel-preset-stage-2": "^6.24.1",
"body-parser": "^1.18.2",
"browser-sync": "^2.18.13",
"caniuse-lite": "^1.0.30000751",
"case-sensitive-paths-webpack-plugin": "^2.1.1",
"colors": "^1.1.2",
"cpx": "^1.5.0",
"cross-env": "^5.1.0",
"cssnano": "^3.10.0",
"enzyme": "^3.1.0",
"enzyme-adapter-react-16": "^1.0.2",
"eslint": "^4.9.0",
"express": "^4.16.2",
"git-pre-push": "0.0.5",
"glob": "^7.1.2",
"karma": "^1.7.1",
"karma-chrome-launcher": "^2.2.0",
"karma-coverage": "^1.1.1",
"karma-mocha": "^1.3.0",
"karma-mocha-reporter": "^2.2.5",
"karma-power-assert": "^1.0.0",
"karma-sourcemap-loader": "^0.3.7",
"karma-sourcemap-writer": "^0.1.2",
"karma-webpack": "^2.0.5",
"mkdirp": "^0.5.1",
"mocha": "^4.0.1",
"nodemon": "^1.12.1",
"npm-run-all": "^4.1.1",
"postcss": "^6.0.13",
"postcss-browser-reporter": "^0.5.0",
"postcss-cli": "^4.1.1",
"postcss-cssnext": "^3.0.2",
"postcss-import": "^11.0.0",
"postcss-reporter": "^5.0.0",
"power-assert": "^1.4.4",
"pre-commit": "^1.2.2",
"pug": "^2.0.0-rc.4",
"react-test-renderer": "^16.0.0",
"rimraf": "^2.6.2",
"sinon": "^4.0.2",
"stylelint": "^8.2.0",
"stylelint-config-standard": "^17.0.0",
"stylelint-order": "^0.7.0",
"ts-loader": "^3.1.0",
"tslint": "5.8.0",
"typescript": "^2.5.3",
"uglify-js": "^3.1.5",
"webpack": "^3.8.1"
},
"pre-commit": [
"lint"
],
"pre-push": [
"test"
],
"browserslist": [
"> 5%",
"last 2 versions"
],
"stylelint": {
"extends": "stylelint-config-standard",
"plugins": [
"stylelint-order"
],
"rules": {
"order/properties-alphabetical-order": true,
"order/order": [
"custom-properties",
"declarations"
]
}
},
"babel": {
"presets": [
"env",
"react",
"stage-2"
],
"plugins": [
"transform-decorators-legacy",
"transform-class-properties",
"syntax-object-rest-spread"
],
"env": {
"test": {
"presets": [
"airbnb",
"power-assert"
]
}
}
}
}
const isProduction = (process.env.NODE_ENV === 'production')
const isDevelopment = (process.env.NODE_ENV === 'development')
module.exports = (context) => ({
parser: context.options.parser,
map: isDevelopment ? { inline: true } : false,
plugins: {
'postcss-import': {
path: ['src/styles'],
},
'postcss-cssnext': {},
'postcss-reporter': {},
'postcss-browser-reporter': {},
'cssnano': isProduction && {
preset: 'default',
},
}
})
{
"compilerOptions": {
"jsx": "react",
"target": "esnext",
"module": "esnext",
"moduleResolution": "node",
"allowSyntheticDefaultImports": true,
"experimentalDecorators": true,
"noImplicitAny": true,
"strictNullChecks": true,
"noUnusedLocals": true,
"removeComments": true,
"importHelpers": true,
"baseUrl": "./src/scripts",
"typeRoots" : [
"types",
"./node_modules/@types"
],
"paths": {
"*": ["*"],
"app": ["./src/scripts/app"]
}
},
"include": [
"./src/scripts/**/*"
],
"exclude": [
"./node_modules"
],
"compileOnSave": false,
"atom": {
"rewriteTsConfig": false
}
}
{
"defaultSeverity": "error",
"rulesDirectory": [],
"rules": {
"class-name": true,
"comment-format": [true, "check-space"],
"curly": true,
"indent": [true, "spaces"],
"max-line-length": [true, 150],
"no-duplicate-imports": true,
"no-duplicate-variable": true,
"no-eval": true,
"no-internal-module": true,
"no-trailing-whitespace": true,
"no-unsafe-finally": true,
"no-unused-variable": [true],
"no-var-keyword": true,
"object-literal-shorthand": true,
"one-line": [
true,
"check-catch",
"check-finally",
"check-else",
"check-open-brace",
"check-whitespace"
],
"prefer-const": true,
"prefer-object-spread": true,
"quotemark": [
true,
"single",
"jsx-double"
],
"restrict-plus-operands": [true],
"semicolon": [true, "never"],
"space-within-parens": 1,
"triple-equals": true,
"trailing-comma": [
true,
{
"multiline": {
"objects": "always",
"arrays": "always",
"functions": "never",
"typeLiterals": "ignore"
},
"singleline": "never"
}
],
"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-operator",
"check-separator",
"check-type"
]
}
}
const path = require('path')
const glob = require('glob')
const webpack = require('webpack')
const CaseSensitivePathsPlugin = require('case-sensitive-paths-webpack-plugin')
const isDevelopment = (process.env.NODE_ENV === 'development')
const isTesting = (process.env.NODE_ENV === 'test')
const combine = base => addition => (
Object.keys(addition).reduce((merged, key) => (
Object.assign(merged, {
[key]: typeof merged[key] !== 'object'
? addition[key]
: merged[key] instanceof Array
? merged[key].concat(addition[key])
: Object.assign(merged[key], addition[key])
})
), base)
)
const base = {
context: path.resolve(__dirname, 'src/scripts'),
plugins: [
new webpack.EnvironmentPlugin(['NODE_ENV']),
new webpack.NoEmitOnErrorsPlugin(),
new CaseSensitivePathsPlugin(),
],
resolve: {
modules: ['node_modules'],
extensions: ['.ts', '.tsx', '.js', '.jsx', '.json'],
alias: {
app: path.resolve(__dirname, 'src/scripts/app'),
},
},
}
const test = combine(base)({
devtool: 'cheap-module-eval-source-map',
externals: {
'react/lib/ExecutionEnvironment': 'react',
'react/lib/ReactContext': 'react',
},
plugins: [
new webpack.optimize.UglifyJsPlugin({
mangle: false,
compress: true,
parallel: {
cache: true,
workers: 4,
},
output: {
comments: true,
beautify: true,
},
}),
],
module: {
rules: [
{
test: /\.tsx?$/,
exclude: ['node_modules'],
use: [
{ loader: 'babel-loader' },
{ loader: 'ts-loader' },
],
},
],
},
})
const entriesDir = __dirname + '/src/scripts/app/entries/'
const common = combine(base)({
entry: glob
.sync('**/*.tsx', { cwd: entriesDir, root: entriesDir })
.reduce((entries, path) => (
Object.assign(entries, { [path.split('.')[0]]: entriesDir + path })
), {
vendor: [
'axios',
'react',
'react-dom',
]
}),
output: {
filename: '[name].js',
path: path.resolve(__dirname, 'public/js'),
jsonpFunction: 'vendor',
},
plugins: [
new webpack.optimize.CommonsChunkPlugin({
name: 'vendor',
minChunks: Infinity,
}),
],
module: {
rules: [
{
test: /\.tsx?$/,
exclude: ['node_modules', /\.test\.tsx?$/],
use: [
{ loader: 'babel-loader' },
{ loader: 'ts-loader' },
],
},
],
},
})
const development = combine(common)({
devtool: 'cheap-module-eval-source-map',
output: {
pathinfo: true,
},
stats: {
errorDetails: true,
colors: true,
},
plugins: [
new webpack.optimize.UglifyJsPlugin({
mangle: false,
compress: true,
parallel: {
cache: true,
workers: 4,
},
output: {
comments: true,
beautify: true,
},
}),
],
})
const production = combine(common)({
plugins: [
new webpack.optimize.UglifyJsPlugin({
mangle: true,
compress: true,
parallel: {
cache: true,
workers: 4,
},
output: {
comments: false,
beautify: false,
},
}),
],
})
module.exports = isTesting ? test : isDevelopment ? development : production
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment