UNPKG

@mikepjb/nx

Version:

Quick start new sites

272 lines (238 loc) 7.29 kB
#!/usr/bin/env node // TODO make nx init.js build arg console.log/build // TODO ensure build step uses production flag. // TODO src/index.js // TODO initial yarn dev/build commands // - build must: // - postcss PRODUCTION + gen static files // TODO provide basic route object // TODO check if git is on path // TODO git init // TODO write initial commit // TODO resolve invalid DOM element class warning (from babel?) // // TODO potentially move index.js file to file from var with: // TODO logging timestamps for server? const chalk = require('chalk') const fs = require('fs') const path = require('path') const process = require('process') const { exec } = require('child_process') var args = process.argv.slice(2) var projectName = 'new-site' if (args.length != 0) { projectName = args[0] } console.log(chalk.blue('==>') + ' nx: creating new site, ' + projectName) var dir = process.cwd() + '/' + projectName if (!fs.existsSync(dir)) { fs.mkdirSync(dir) } else { console.error(chalk.red('! ') + 'the directory, ' + dir + ' already exists') process.exit(0) } if (!fs.existsSync(dir + '/src')) fs.mkdirSync(dir + '/src') // Templates {{{ var packageJson = `{ "name": "${projectName}", "description": "website for ${projectName}", "version": "0.0.1", "main": "index.js", "license": "UNLICENSED", "private": "true", "scripts": { "build": "babel-node init.js build", "build:css": "postcss ./src/style.css -o ./public/style.css", "dev": "npm start", "ensure:css": "[ ! -f ./public/style.css ] && npm run build:css; true", "ensure:lib": "[ ! -d node_modules ] && npm install --prefer-offline; true", "prestart": "npm run ensure:lib; npm run ensure:css", "start": "[ ! -d node_modules ] && npm i; babel-node init.js" }, "dependencies": { "@babel/core": "^7.8.3", "@babel/node": "^7.8.3", "@babel/preset-env": "^7.8.3", "@babel/preset-react": "^7.8.3", "@babel/runtime": "^7.8.3", "@fullhuman/postcss-purgecss": "^2.0.5", "autoprefixer": "^9.7.4", "chokidar": "^3.3.1", "cssnano": "^4.1.10", "express": "^4.17.1", "postcss": "^7.0.26", "postcss-cli": "^7.1.0", "react": "^16.12.0", "react-dom": "^16.12.0", "tailwindcss": "^1.1.4", "ws": "^7.2.1" }, "babel": { "presets": [ "@babel/preset-env", "@babel/preset-react" ] } }` var init = `import express from 'express' import fs from 'fs' import WebSocket from 'ws' import chokidar from 'chokidar' import process from 'process' var args = process.argv.splice(2) var devServer = () => { var server = express() var reloadingSocket = new WebSocket.Server({port: 7777}) var fileWatcher = chokidar.watch('./src') reloadingSocket.on('connection', () => console.log('browser connected')) fileWatcher.on('ready', () => { fileWatcher.on('all', () => { console.log('file changed') Object.keys(require.cache).forEach((id) => { if (/[\\\/\\\\]src[\\\/\\\\]/.test(id)) delete require.cache[id] reloadingSocket.clients.forEach((client) => { if (client.readyState === WebSocket.OPEN) { client.send('reload!') } }) }) }) }) server.get('/', (req, res, next) => require('./src/index')(req, res, next)) server.get('/style.css', (req, res) => res.type('css') && res.sendFile(__dirname + '/public/style.css')) server.get('/status.json', (req, res, next) => res.json({"status": "started"})) server.listen(8080, '0.0.0.0', () => console.log('server started on 8080')) } var build = () => { console.log('building content.. writing to ./public') if (!fs.existsSync('./public')) fs.mkdirSync('./public') fs.writeFileSync('public/index.html', 'something.') } if (args.length != 0 && args[0] === 'build') { build() } else { devServer() } ` var postcssConfig = `const purgecss = require('@fullhuman/postcss-purgecss') const cssnano = require('cssnano') module.exports = { plugins: [ require('tailwindcss'), require('autoprefixer'), process.env.NODE_ENV === 'production' ? cssnano({ preset: 'default' }) : null, process.env.NODE_ENV === 'production' && purgecss({ content: ['./layouts/**/*.html', './src/**/*.vue', './src/**/*.jsx'], defaultExtractor: content => content.match(/[\w-/:]+(?<!:)/g) || [] }) ] } ` var tailwindConfig = `module.exports = { theme: { extend: {} }, variants: {}, plugins: [] } ` var style = `@tailwind base; @tailwind components; @tailwind utilities; ` var gitignore = `node_modules/ public/ ` var index = `import React from 'react' import ReactDOMServer from 'react-dom/server' import Express from 'express' import fs from 'fs' const Sun = () => <svg class="inline-block h-5 w-5 fill-current text-gray-400"> <circle cx="10" cy="10" r="10" strokeWidth="2"/> </svg> const reloadScript = \`<script> var port = 7777 var ws = new WebSocket(\\\`ws://\\\${window.location.hostname}:\\\${port}\\\`) ws.onopen = function() { console.log(\\\`connected to the development server: \\\${window.location.hostname}:\\\${port}\\\`) } ws.onmessage = function() { console.log('refreshing page') ws.close() location.reload() } </script>\` const Page = (content) => \`<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"> <link rel="stylesheet" href="style.css" media="all"> <title></title> </head> <body> \${content} \${reloadScript} </body> </html>\` class Index extends React.Component { render() { return <div class="bg-gray-100 text-gray-900 antialiased min-h-screen"> <nav class="p-5 bg-gray-900 text-gray-100 flex justify-between text-lg shadow-md"> <div class="flex items-center"> <Sun/><span class="ml-2">Dawn of a new site</span> </div> <div>some menu items</div> </nav> <div class="m-5">Welcome.</div> </div> } } var staticContent = ReactDOMServer.renderToStaticMarkup(<Index/>) module.exports = (req, res) => res.send(Page(staticContent)) ` // }}} function write(name, dir, content) { var filepath = `${dir}/${name}` console.log(chalk.yellow(' ->') + ` writing ${name}`) if (!fs.existsSync(filepath)) { fs.writeFileSync(filepath, content) } else { console.log(chalk.red('!!') + ` ${name} already exists, skipping..`) } } console.log(dir) write('init.js', dir, init) write('package.json', dir, packageJson) write('postcss.config.js', dir, postcssConfig) write('tailwind.config.js', dir, tailwindConfig) write('.gitignore', dir, gitignore) write('src/style.css', dir, style) write('src/index.js', dir, index) exec('git rev-parse 2> /dev/null', (gerr) => { if (gerr !== null) { exec(`command -v git && cd ${dir} && git init`, (err) => { if (err) { console.error(chalk.red(' !') + ' could not initialise git, ' + err) } else { console.log(chalk.yellow(' ->') + ' initialised git repository') exec(`cd ${dir} && git add --all && git commit -m 'Initial Commit'`) } }) } else { console.log(chalk.blue(' ?') + ' inside a git repo, skipping creation') } })