diff --git a/.eslintrc.js b/.eslintrc.js index d0c335c9..f894ee6f 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -5,6 +5,9 @@ module.exports = { es6: true, node: true }, + parserOptions: { + ecmaVersion: 6 + }, extends: ['eslint:recommended'], plugins: ['prettier'], rules: { diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 00000000..db1bca68 --- /dev/null +++ b/.prettierrc @@ -0,0 +1,3 @@ +{ + singleQuote: true +} diff --git a/.travis.yml b/.travis.yml index b5ec28a4..551b3605 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,8 +3,6 @@ sudo: required node_js: - '9' - '8' - - '7' - - '6' addons: apt: packages: diff --git a/README.md b/README.md index 5e51ebc1..8f463900 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,7 @@ Create a production build with `elm-app build` ### Installation -**Node >=6** is required for installation. +**Node >=8** is required for installation. #### Yarn diff --git a/appveyor.yml b/appveyor.yml index f044938f..0a7d942f 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -3,6 +3,13 @@ image: Visual Studio 2017 platform: - x64 +# Test against these versions of Node.js. +environment: + matrix: + # node.js + - nodejs_version: "8" + - nodejs_version: "9" + install: - ps: Install-Product node $env:nodejs_version $env:platform diff --git a/bin/elm-app-cli.js b/bin/elm-app-cli.js index 0356dabf..17171c46 100755 --- a/bin/elm-app-cli.js +++ b/bin/elm-app-cli.js @@ -94,7 +94,7 @@ function help(version) { * Spawn separate node process with specified script * * @param {string} script Path to script - * @param {Arrays} args Script arguments + * @param {Array} args Script arguments * @return {undefined} */ function spawnSyncNode(script, args) { diff --git a/config/polyfills.js b/config/polyfills.js new file mode 100644 index 00000000..5c1d8666 --- /dev/null +++ b/config/polyfills.js @@ -0,0 +1,16 @@ +'use strict'; + +if (typeof Promise === 'undefined') { + // Rejection tracking prevents a common issue where React gets into an + // inconsistent state due to an error, but it gets swallowed by a Promise, + // and the user has no idea what causes React's erratic future behavior. + require('promise/lib/rejection-tracking').enable(); + window.Promise = require('promise/lib/es6-extensions.js'); +} + +// fetch() polyfill for making API calls. +require('whatwg-fetch'); + +// Object.assign() is commonly used with React. +// It will use the native implementation if it's present and isn't buggy. +Object.assign = require('object-assign'); diff --git a/config/webpack.config.dev.js b/config/webpack.config.dev.js index 8bc8c626..7b95b052 100644 --- a/config/webpack.config.dev.js +++ b/config/webpack.config.dev.js @@ -1,12 +1,11 @@ 'use strict'; -const path = require('path'); const autoprefixer = require('autoprefixer'); -const HotModuleReplacementPlugin = require('webpack/lib/HotModuleReplacementPlugin'); -const DefinePlugin = require('webpack/lib/DefinePlugin'); -const NamedModulesPlugin = require('webpack/lib/NamedModulesPlugin'); -const InterpolateHtmlPlugin = require('react-dev-utils/InterpolateHtmlPlugin'); +const path = require('path'); +const webpack = require('webpack'); const HtmlWebpackPlugin = require('html-webpack-plugin'); +const CaseSensitivePathsPlugin = require('case-sensitive-paths-webpack-plugin'); +const InterpolateHtmlPlugin = require('react-dev-utils/InterpolateHtmlPlugin'); const getClientEnvironment = require('./env'); const paths = require('../config/paths'); @@ -20,10 +19,20 @@ const publicUrl = ''; // Get environment variables to inject into our app. const env = getClientEnvironment(publicUrl); +// This is the development configuration. +// It is focused on developer experience and fast rebuilds. +// The production configuration is different and lives in a separate file. module.exports = { + mode: 'development', + // You may want 'eval' instead if you prefer to see the compiled output in DevTools. + // See the discussion in https://github.com/facebook/create-react-app/issues/343. devtool: 'cheap-module-source-map', - + // These are the "entry points" to our application. + // This means they will be the "root" imports that are included in JS bundle. + // The first two entry points enable "hot" CSS and auto-refreshes for JS. entry: [ + // We ship a few polyfills by default: + require.resolve('./polyfills'), // Include an alternative client for WebpackDevServer. A client's job is to // connect to WebpackDevServer by a socket and get notified about changes. // When you save a file, the client will either apply hot updates (in case @@ -42,34 +51,44 @@ module.exports = { paths.appIndexJs ], - output: { + // Add /* filename */ comments to generated require()s in the output. pathinfo: true, - - // The build folder. - path: paths.appBuild, - // This does not produce a real file. It's just the virtual path that is // served by WebpackDevServer in development. This is the JS bundle // containing code from all our entry points, and the Webpack runtime. filename: 'static/js/bundle.js', - + // There are also additional JS chunk files if you use code splitting. + chunkFilename: 'static/js/[name].chunk.js', + // This is the URL that app is served from. We use "/" in development. publicPath: publicPath, - // Point sourcemap entries to original disk location (format as URL on Windows) devtoolModuleFilenameTemplate: info => path.resolve(info.absoluteResourcePath).replace(/\\/g, '/') }, - + optimization: { + // Automatically split vendor and commons + // https://twitter.com/wSokra/status/969633336732905474 + // https://medium.com/webpack/webpack-4-code-splitting-chunk-graph-and-the-splitchunks-optimization-be739a861366 + splitChunks: { + chunks: 'all', + name: 'vendors' + }, + // Keep the runtime chunk seperated to enable long term caching + // https://twitter.com/wSokra/status/969679223278505985 + runtimeChunk: true + }, resolve: { modules: ['node_modules'], extensions: ['.js', '.elm'] }, - module: { noParse: /\.elm$/, - + strictExportPresence: true, rules: [ + // Disable require.ensure as it's not a standard language feature. + { parser: { requireEnsure: false } }, + { test: /\.js$/, exclude: [/[/\\\\]elm-stuff[/\\\\]/, /[/\\\\]node_modules[/\\\\]/], @@ -169,8 +188,9 @@ module.exports = { // "style" loader turns CSS into JS modules that inject