diff --git a/.eslintignore b/.eslintignore index a72d1b22..e328c937 100644 --- a/.eslintignore +++ b/.eslintignore @@ -1 +1,3 @@ elm-stuff/ +template/ +tests/ diff --git a/.gitignore b/.gitignore index fc6b3c2a..a2c002a1 100644 --- a/.gitignore +++ b/.gitignore @@ -89,8 +89,10 @@ elm-stuff repl-temp-* # create-elm-app -template/dist +template/build template/package.json +template/scripts/ +template/config/ # Desktop Services Store on macOS .DS_Store diff --git a/README.md b/README.md index 8bab9d2e..810e1f96 100644 --- a/README.md +++ b/README.md @@ -19,8 +19,14 @@ Create a production build with `elm-app build` ## Getting Started ### Installation -Node >=4 is required only as a build dependency. +Node >=6 is required as a dependency. + +#### Yarn + +`yarn global add create-elm-app` + +#### NPM `npm install create-elm-app -g` If you are running Linux OS, you should install it as the superuser: @@ -45,10 +51,11 @@ my-app/ .gitignore README.md elm-package.json - src/ - App.elm + public/ favicon.ico index.html + src/ + App.elm index.js main.css tests/ @@ -105,12 +112,23 @@ Inspired by [create-react-app](https://github.com/facebookincubator/create-react * **No Lock-In:** You can “eject” to a custom setup at any time. Run a single command, and all the configuration and build dependencies will be moved directly into your project, so you can pick up right where you left off. +## What is inside + +The tools used by Create React App are subject to change. +Currently it is a thin layer on top of many amazing community projects, such as: + +* [elm-platform](https://github.com/elm-lang/elm-platform) +* [elm-test](https://github.com/elm-community/elm-test) +* [webpack](https://webpack.js.org/) with [webpack-dev-server](https://github.com/webpack/webpack-dev-server), [html-webpack-plugin](https://github.com/ampedandwired/html-webpack-plugin) and [style-loader](https://github.com/webpack/style-loader) +* [Babel](http://babeljs.io/) with ES6 +* [Autoprefixer](https://github.com/postcss/autoprefixer) +* and others. + +All of them are transitive dependencies of the provided npm package. + ## Contributing We would love to get you involved! Please check our [Contributing Guide](CONTRIBUTING.md) to get started! -## What is inside -This tool contains a local installation of [elm-platform](https://github.com/elm-lang/elm-platform) and heavily relies on [webpack](https://github.com/webpack/webpack) in the build process. - ## Alternatives - [elm-webpack-starter](https://github.com/moarwick/elm-webpack-starter) - [elm-app-boilerplate](https://github.com/gkubisa/elm-app-boilerplate) diff --git a/bin/create-elm-app-cli.js b/bin/create-elm-app-cli.js index df976cc1..ed4592c3 100755 --- a/bin/create-elm-app-cli.js +++ b/bin/create-elm-app-cli.js @@ -1,22 +1,26 @@ #!/usr/bin/env node -const path = require('path') -const spawn = require('cross-spawn') -const argv = require('minimist')(process.argv.slice(2)) -const version = require('../package.json').version -const elmPlatformVersion = require('elm/package.json').version -const commands = argv._ +'use strict'; + +const path = require('path'); +const spawn = require('cross-spawn'); +const argv = require('minimist')(process.argv.slice(2)); +const version = require('../package.json').version; +const elmPlatformVersion = require('elm/package.json').version; +const commands = argv._; if (commands.length === 0) { - console.log('\nUsage: create-elm-app \n') - console.log('where is the name of the directory with your future project') - console.log('\nElm Platform ' + elmPlatformVersion + '\n') - console.log('create-elm-app@' + version + ' ' + path.resolve(__dirname, '..')) - process.exit(1) + console.log('\nUsage: create-elm-app \n'); + console.log( + 'where is the name of the directory with your future project' + ); + console.log('\nElm Platform ' + elmPlatformVersion + '\n'); + console.log( + 'create-elm-app@' + version + ' ' + path.resolve(__dirname, '..') + ); + process.exit(1); } -spawn.sync( - 'node', - [ path.resolve(__dirname, '../scripts/create'), commands ], - { stdio: 'inherit' } -) +spawn.sync('node', [path.resolve(__dirname, '../scripts/create'), commands], { + stdio: 'inherit' +}); diff --git a/bin/elm-app-cli.js b/bin/elm-app-cli.js index 7f890776..314f829e 100755 --- a/bin/elm-app-cli.js +++ b/bin/elm-app-cli.js @@ -1,22 +1,23 @@ #!/usr/bin/env node -const path = require('path') -const spawn = require('cross-spawn') -const argv = require('minimist')(process.argv.slice(2)) -const executablePaths = require('elm/platform').executablePaths +'use strict'; -const version = require('../package.json').version -const elmPlatformVersion = require('elm/package.json').version +const path = require('path'); +const spawn = require('cross-spawn'); +const argv = require('minimist')(process.argv.slice(2)); +const executablePaths = require('elm/platform').executablePaths; +const version = require('../package.json').version; +const elmPlatformVersion = require('elm/package.json').version; -const commands = argv._ +const commands = argv._; if (commands.length === 0) { - help(version) - process.exit(1) + help(version); + process.exit(1); } -const script = commands[ 0 ] -const scriptArgs = commands.splice(1) +const script = commands[0]; +const scriptArgs = commands.splice(1); switch (script) { case 'create': @@ -24,44 +25,43 @@ switch (script) { case 'eject': case 'start': spawnSyncNode(path.resolve(__dirname, '../scripts', script), scriptArgs); - break + break; case 'test': { - let args = [] - Object.keys(argv || {}).forEach(function (key) { + let args = []; + Object.keys(argv || {}).forEach(key => { if (key !== '_' && key !== 'compiler') { - args = args.concat([ '--' + key, argv[ key ] ]) + args = args.concat(['--' + key, argv[key]]); } - }) + }); - args = args.concat([ '--compiler', path.normalize(executablePaths[ 'elm-make' ]) ]) + args = args.concat([ + '--compiler', + path.normalize(executablePaths['elm-make']) + ]); - const cp = spawn.sync( - require.resolve('elm-test/bin/elm-test'), - args, - { stdio: 'inherit' } - ) + const cp = spawn.sync(require.resolve('elm-test/bin/elm-test'), args, { + stdio: 'inherit' + }); if (cp.status !== 0) { - process.exit(cp.status) + process.exit(cp.status); } - break + break; } default: // Proxy elm-platform cli commands. - if ([ 'package', 'reactor', 'make', 'repl' ].indexOf(script) !== -1) { - const executable = executablePaths[ 'elm-' + script ] + if (['package', 'reactor', 'make', 'repl'].indexOf(script) !== -1) { + const executable = executablePaths['elm-' + script]; - spawn.sync( - path.normalize(executable), - process.argv.slice(3), - { stdio: 'inherit' } - ) - break + spawn.sync(path.normalize(executable), process.argv.slice(3), { + stdio: 'inherit' + }); + break; } else { - help(version) - process.exit(1) + help(version); + process.exit(1); } } @@ -71,12 +71,14 @@ switch (script) { * @param {string} version [description] * @return {undefined} */ -function help (version) { - console.log('\nUsage: elm-app \n') - console.log('where is one of:') - console.log(' create, build, start, package, reactor, make, repl\n') - console.log('\nElm ' + elmPlatformVersion + '\n') - console.log('create-elm-app@' + version + ' ' + path.resolve(__dirname, '..')) +function help(version) { + console.log('\nUsage: elm-app \n'); + console.log('where is one of:'); + console.log(' create, build, start, package, reactor, make, repl\n'); + console.log('\nElm ' + elmPlatformVersion + '\n'); + console.log( + 'create-elm-app@' + version + ' ' + path.resolve(__dirname, '..') + ); } /** @@ -86,14 +88,12 @@ function help (version) { * @param {Arrays} args Script arguments * @return {undefined} */ -function spawnSyncNode (script, args) { - const cp = spawn.sync( - 'node', - [ script ].concat(args || []), - { stdio: 'inherit' } - ) +function spawnSyncNode(script, args) { + const cp = spawn.sync('node', [script].concat(args || []), { + stdio: 'inherit' + }); if (cp.status !== 0) { - process.exit(cp.status) + process.exit(cp.status); } } diff --git a/config/env.js b/config/env.js index 6827ce27..83f2be82 100644 --- a/config/env.js +++ b/config/env.js @@ -1,10 +1,10 @@ -function getClientEnvironment () { - return Object - .keys(process.env) - .reduce((acc, current) => { - acc[ `process.env.${current}` ] = `"${process.env[ current ]}"` - return acc - }, {}) +'use strict'; + +function getClientEnvironment() { + return Object.keys(process.env).reduce((acc, current) => { + acc[`process.env.${current}`] = `"${process.env[current]}"`; + return acc; + }, {}); } -module.exports = getClientEnvironment +module.exports = getClientEnvironment; diff --git a/config/paths.js b/config/paths.js index d71a0ab3..4a7aeeb3 100644 --- a/config/paths.js +++ b/config/paths.js @@ -1,16 +1,52 @@ -const path = require('path') +'use strict'; -const appRoot = process.cwd() +const path = require('path'); +const fs = require('fs'); +const url = require('url'); -let paths = { - appRoot, - entry: path.resolve('./src/index.js'), - dist: path.resolve('./dist'), - template: path.resolve('./src/index.html'), - favicon: path.resolve('./src/favicon.ico'), - elmPkg: path.resolve('elm-package.json'), - elmMake: require('elm/platform').executablePaths['elm-make'], - servedPath: './' || process.env.SERVED_PATH +// Make sure any symlinks in the project folder are resolved: +// https://github.com/facebookincubator/create-react-app/issues/637 +const appDirectory = fs.realpathSync(process.cwd()); +const resolveApp = relativePath => path.resolve(appDirectory, relativePath); + +const envPublicUrl = process.env.PUBLIC_URL; + +function ensureSlash(path, needsSlash) { + const hasSlash = path.endsWith('/'); + if (hasSlash && !needsSlash) { + return path.substr(path, path.length - 1); + } else if (!hasSlash && needsSlash) { + return `${path}/`; + } + return path; } -module.exports = paths +const getPublicUrl = appPackageJson => + envPublicUrl || require(appPackageJson).homepage; + +// We use `PUBLIC_URL` environment variable or "homepage" field to infer +// "public path" at which the app is served. +// Webpack needs to know it to put the right