Skip to content

Commit

Permalink
Merge pull request #138 from halfzebra/revising-template-structure
Browse files Browse the repository at this point in the history
Revising template structure
  • Loading branch information
halfzebra authored Jun 24, 2017
2 parents 4e9e42e + db88cbb commit 167f0c1
Show file tree
Hide file tree
Showing 27 changed files with 995 additions and 709 deletions.
2 changes: 2 additions & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
elm-stuff/
template/
tests/
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
30 changes: 24 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand All @@ -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/
Expand Down Expand Up @@ -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)
Expand Down
36 changes: 20 additions & 16 deletions bin/create-elm-app-cli.js
Original file line number Diff line number Diff line change
@@ -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 <project-directory>\n')
console.log('where <project-directory> 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 <project-directory>\n');
console.log(
'where <project-directory> 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'
});
94 changes: 47 additions & 47 deletions bin/elm-app-cli.js
Original file line number Diff line number Diff line change
@@ -1,67 +1,67 @@
#!/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':
case 'build':
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);
}
}

Expand All @@ -71,12 +71,14 @@ switch (script) {
* @param {string} version [description]
* @return {undefined}
*/
function help (version) {
console.log('\nUsage: elm-app <command>\n')
console.log('where <command> 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 <command>\n');
console.log('where <command> 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, '..')
);
}

/**
Expand All @@ -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);
}
}
16 changes: 8 additions & 8 deletions config/env.js
Original file line number Diff line number Diff line change
@@ -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;
60 changes: 48 additions & 12 deletions config/paths.js
Original file line number Diff line number Diff line change
@@ -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 <script> hrefs into HTML even in
// single-page apps that may serve index.html for nested URLs like /todos/42.
// We can't use a relative path in HTML because we don't want to load something
// like /todos/42/static/js/bundle.7289d.js. We have to know the root.
function getServedPath(appPackageJson) {
const publicUrl = getPublicUrl(appPackageJson);
const servedUrl =
envPublicUrl || (publicUrl ? url.parse(publicUrl).pathname : '/');
return ensureSlash(servedUrl, true);
}

module.exports = {
appPath: resolveApp('.'),
appPublic: resolveApp('./public'),
appHtml: resolveApp('./public/index.html'),
appIndexJs: resolveApp('./src/index.js'),
appSrc: resolveApp('./src'),
entry: resolveApp('./src/index.js'),
appBuild: resolveApp('./build'),
elmPackageJson: resolveApp('./elm-package.json'),
elmMake: require('elm/platform').executablePaths['elm-make'],
publicUrl: getPublicUrl(resolveApp('elm-package.json')),
servedPath: getServedPath(resolveApp('elm-package.json'))
};
Loading

0 comments on commit 167f0c1

Please sign in to comment.