Skip to content

Instantly share code, notes, and snippets.

@akimach
Created November 8, 2017 10:14
Show Gist options
  • Save akimach/e8c8c6bfc16cabfcba016b661088b6cf to your computer and use it in GitHub Desktop.
Save akimach/e8c8c6bfc16cabfcba016b661088b6cf to your computer and use it in GitHub Desktop.
Generate a skelton of react.
#!/usr/bin/env python
#!coding: utf-8
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
import sys
import os, os.path
import subprocess
import json
from collections import OrderedDict
PACKAGES = '''
webpack
webpack-dev-server
babel-core
babel-loader
babel-preset-react
babel-preset-env
node-sass
style-loader
css-loader
sass-loader
import-glob-loader
extract-text-webpack-plugin
eslint
eslint-plugin-react
eslint-config-airbnb
eslint-plugin-import
eslint-plugin-jsx-a11y
react
react-dom
'''
GITIGNORE = '''### https://raw.github.com/github/gitignore/35c010258fc790ad769033e9ccfb1021178f2925/Global/Linux.gitignore
*~
# temporary files which can be created if a process still has a handle open of a deleted file
.fuse_hidden*
# KDE directory preferences
.directory
# Linux trash folder which might appear on any partition or disk
.Trash-*
# .nfs files are created when an open file is removed but is still being accessed
.nfs*
### https://raw.github.com/github/gitignore/35c010258fc790ad769033e9ccfb1021178f2925/Global/Windows.gitignore
# Windows thumbnail cache files
Thumbs.db
ehthumbs.db
ehthumbs_vista.db
# Folder config file
Desktop.ini
# Recycle Bin used on file shares
$RECYCLE.BIN/
# Windows Installer files
*.cab
*.msi
*.msm
*.msp
# Windows shortcuts
*.lnk
### https://raw.github.com/github/gitignore/35c010258fc790ad769033e9ccfb1021178f2925/Global/macOS.gitignore
*.DS_Store
.AppleDouble
.LSOverride
# Icon must end with two \r
Icon
# Thumbnails
._*
# Files that might appear in the root of a volume
.DocumentRevisions-V100
.fseventsd
.Spotlight-V100
.TemporaryItems
.Trashes
.VolumeIcon.icns
.com.apple.timemachine.donotpresent
# Directories potentially created on remote AFP share
.AppleDB
.AppleDesktop
Network Trash Folder
Temporary Items
.apdisk
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# Runtime data
pids
*.pid
*.seed
*.pid.lock
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
# Coverage directory used by tools like istanbul
coverage
# nyc test coverage
.nyc_output
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
.grunt
# Bower dependency directory (https://bower.io/)
bower_components
# node-waf configuration
.lock-wscript
# Compiled binary addons (http://nodejs.org/api/addons.html)
build/Release
# Dependency directories
node_modules/
jspm_packages/
# Typescript v1 declaration files
typings/
# Optional npm cache directory
.npm
# Optional eslint cache
.eslintcache
# Optional REPL history
.node_repl_history
# Output of 'npm pack'
*.tgz
# Yarn Integrity file
.yarn-integrity
# dotenv environment variables file
.env
'''
webpack_config_js = '''const path = require('path');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const publidDir = path.join(__dirname, '/public');
module.exports = [
{
entry: [
'./src/index.jsx',
],
output: {
path: publidDir,
publicPath: '/',
filename: 'bundle.js',
},
module: {
loaders: [{
exclude: /node_modules/,
loader: 'babel-loader',
query: {
presets: ['react', 'env'],
},
}],
},
resolve: {
extensions: ['.js', '.jsx'],
},
devServer: {
historyApiFallback: true,
contentBase: publidDir,
},
},
{
entry: {
style: './stylesheets/index.scss',
},
output: {
path: publidDir,
publicPath: '/',
filename: 'bundle.css',
},
module: {
loaders: [
{
test: /\.css$/,
loader: ExtractTextPlugin.extract({ fallback: 'style-loader', use: 'css-loader' }),
},
{
test: /\.scss$/,
loader: ExtractTextPlugin.extract({ fallback: 'style-loader', use: 'css-loader!sass-loader' }),
},
],
},
plugins: [
new ExtractTextPlugin('bundle.css'),
],
},
];
'''
eslintrc_js = '''module.exports = {
"extends": "airbnb",
"env": {
"browser": true,
"es6": true,
},
"rules": {
"semi": 0,
}
};
'''
index_html = '''<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Hello, world!</title>
<link rel="stylesheet" href="bundle.css" />
</head>
<body>
<div class="container"></div>
</body>
<script src="bundle.js" charset="utf-8"></script>
</html>
'''
index_jsx = '''import React from 'react'
import ReactDOM from 'react-dom'
import App from './components/App'
ReactDOM.render(<App />, document.querySelector('.container'))
'''
app_jsx = '''import React, { Component } from 'react'
class App extends Component {
constructor(props) {
super(props)
this.state = {}
}
render() {
return (<h1>Hello, world!</h1>)
}
}
export default App
'''
index_scss = ''''''
DIRECTORIES = ['./public', './src', './stylesheets', './src/components', ]
TEMPLATES = {
'./.eslintrc.js': eslintrc_js,
'./webpack.config.js': webpack_config_js,
'./public/index.html': index_html,
'./src/index.jsx': index_jsx,
'./src/components/App.jsx': app_jsx,
'./stylesheets/index.scss': index_scss,
}
def init(gitignore, force=False):
try:
if force:
subprocess.check_call(['yarn', 'init', '--yes', ])
else:
subprocess.check_call(['yarn', 'init', ])
if not os.path.exists('./.git/'):
subprocess.check_call(['git', 'init', ])
with open('./.gitignore', 'w') as fout:
fout.write(gitignore)
subprocess.check_call(['git', 'add', '.gitignore'])
subprocess.check_call(['git', 'commit', '-m', '"Create .gitignore."'])
print('Initialization succeeded.')
except Exception as e:
print('Initialization failed.', e)
sys.exit(1)
def install_packages(packages):
try:
if os.path.exists('./yarn.lock'):
subprocess.check_call(['yarn','install',])
else:
subprocess.check_call(['yarn','add',] + packages)
with open('./package.json') as f:
json_dic = json.load(f, object_pairs_hook=OrderedDict)
json_dic["scripts"] = {'start':'./node_modules/.bin/webpack-dev-server'}
json_text = json.dumps(OrderedDict(json_dic), indent=2)
with open('./package.json', 'w') as f:
f.write(json_text)
print('Packages installation succeeded.')
except Exception as e:
print('Packages installation failed.', e)
sys.exit(1)
def setup_eslint():
try:
#subprocess.check_call(['git', 'init', ])
subprocess.check_call(['yarn','install',])
print('ES Lint setup succeeded.')
except Exception as e:
print('ES Lint setup failed.')
sys.exit(1)
def setup_templates(directories, templates):
try:
for d in directories:
print(d)
if not os.path.exists(d):
os.mkdir(d)
for f, t in templates.items():
print(f)
with open(f, 'w') as fout:
fout.write(t)
print('Templates setup succeeded.')
except Exception as e:
print('Templates setup failed.')
sys.exit(1)
def finilize():
try:
pass
subprocess.check_call(['git', 'add', '.'])
subprocess.check_call(['git', 'commit', '-m', '"Generate skeleton."'])
except Exception as e:
print(e)
sys.exit(1)
if __name__ == '__main__':
init(GITIGNORE, force=True)
install_packages(PACKAGES.split())
setup_eslint()
setup_templates(DIRECTORIES, TEMPLATES)
finilize()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment