diff --git a/package.json b/package.json index 909b6cd56..58096d3e4 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "preact-cli", - "version": "1.2.0", + "version": "1.3.0", "description": "Start building a Preact Progressive Web App in seconds.", "main": "lib/index.js", "bin": { diff --git a/src/lib/babel-config.js b/src/lib/babel-config.js index 7a8162f3c..80dcbd424 100644 --- a/src/lib/babel-config.js +++ b/src/lib/babel-config.js @@ -1,4 +1,5 @@ export default (env, options={}) => ({ + babelrc: false, presets: [ [require.resolve('babel-preset-env'), { loose: true, diff --git a/src/lib/webpack/dummy-loader.js b/src/lib/webpack/dummy-loader.js index 5155a0702..7f4bd26e6 100644 --- a/src/lib/webpack/dummy-loader.js +++ b/src/lib/webpack/dummy-loader.js @@ -1,3 +1,3 @@ module.exports = function(source, map) { - this.callback(null, source, map); + this.callback(null, source, map); }; diff --git a/src/lib/webpack/transform-config.js b/src/lib/webpack/transform-config.js index 5568aceb5..6ae9b2c59 100644 --- a/src/lib/webpack/transform-config.js +++ b/src/lib/webpack/transform-config.js @@ -17,7 +17,7 @@ export default async function (env, config, ssr = false) { } require('babel-register')({ - presets: ['env'] + presets: [require.resolve('babel-preset-env')] }); const m = require(transformerPath); const transformer = m && m.default || m; @@ -38,25 +38,25 @@ class WebpackConfigHelpers { this._cwd = cwd; } - /** - * Webpack module used to create config. - * - * @readonly - * @returns {object} - * @memberof WebpackConfigHelpers - */ + /** + * Webpack module used to create config. + * + * @readonly + * @returns {object} + * @memberof WebpackConfigHelpers + */ get webpack() { return webpack; } - /** - * Returns wrapper around all loaders from config. - * - * @param {object} config - [webpack config](https://webpack.js.org/configuration/#options). - * @returns {LoaderWrapper[]} - * - * @memberof WebpackConfigHelpers - */ + /** + * Returns wrapper around all loaders from config. + * + * @param {object} config - [webpack config](https://webpack.js.org/configuration/#options). + * @returns {LoaderWrapper[]} + * + * @memberof WebpackConfigHelpers + */ getLoaders(config) { return this.getRules(config).map(({ rule, index }) => ({ rule: rule, @@ -65,57 +65,57 @@ class WebpackConfigHelpers { })); } - /** - * Returns wrapper around all rules from config. - * - * @param {object} config - [webpack config](https://webpack.js.org/configuration/#options). - * @returns {RuleWrapper[]} - * - * @memberof WebpackConfigHelpers - */ + /** + * Returns wrapper around all rules from config. + * + * @param {object} config - [webpack config](https://webpack.js.org/configuration/#options). + * @returns {RuleWrapper[]} + * + * @memberof WebpackConfigHelpers + */ getRules(config) { return [...(config.module.loaders || []), ...(config.module.rules || [])] .map((rule, index) => ({ index, rule })); } - /** - * Returns wrapper around all plugins from config. - * - * @param {object} config - [webpack config](https://webpack.js.org/configuration/#options). - * @returns {PluginWrapper[]} - * - * @memberof WebpackConfigHelpers - */ + /** + * Returns wrapper around all plugins from config. + * + * @param {object} config - [webpack config](https://webpack.js.org/configuration/#options). + * @returns {PluginWrapper[]} + * + * @memberof WebpackConfigHelpers + */ getPlugins(config) { return (config.plugins || []).map((plugin, index) => ({ index, plugin })); } - /** - * - * - * @param {object} config - [webpack config](https://webpack.js.org/configuration/#options). - * @param {string} file - path to test against loader. Resolved relatively to $PWD. - * @returns {RuleWrapper[]} - * - * @memberof WebpackConfigHelpers - */ + /** + * + * + * @param {object} config - [webpack config](https://webpack.js.org/configuration/#options). + * @param {string} file - path to test against loader. Resolved relatively to $PWD. + * @returns {RuleWrapper[]} + * + * @memberof WebpackConfigHelpers + */ getRulesByMatchingFile(config, file) { let filePath = path.resolve(this._cwd, file); return this.getRules(config) .filter(w => w.rule.test && w.rule.test.exec(filePath)); } - /** - * Returns loaders that match provided name. - * - * @example - * helpers.getLoadersByName(config, 'less-loader') - * @param {object} config - [webpack config](https://webpack.js.org/configuration/#options). - * @param {string} name - name of loader. - * @returns {LoaderWrapper[]} - * - * @memberof WebpackConfigHelpers - */ + /** + * Returns loaders that match provided name. + * + * @example + * helpers.getLoadersByName(config, 'less-loader') + * @param {object} config - [webpack config](https://webpack.js.org/configuration/#options). + * @param {string} name - name of loader. + * @returns {LoaderWrapper[]} + * + * @memberof WebpackConfigHelpers + */ getLoadersByName(config, name) { return this.getLoaders(config) .map(({ rule, ruleIndex, loaders }) => Array.isArray(loaders) @@ -126,46 +126,46 @@ class WebpackConfigHelpers { .filter(({ loader }) => loader === name || (loader && loader.loader === name)); } - /** - * Returns plugins that match provided name. - * - * @example - * helpers.getPluginsByName(config, 'HtmlWebpackPlugin') - * @param {object} config - [webpack config](https://webpack.js.org/configuration/#options). - * @param {string} name - name of loader. - * @returns {PluginWrapper[]} - * - * @memberof WebpackConfigHelpers - */ + /** + * Returns plugins that match provided name. + * + * @example + * helpers.getPluginsByName(config, 'HtmlWebpackPlugin') + * @param {object} config - [webpack config](https://webpack.js.org/configuration/#options). + * @param {string} name - name of loader. + * @returns {PluginWrapper[]} + * + * @memberof WebpackConfigHelpers + */ getPluginsByName(config, name) { return this.getPlugins(config) .filter(w => w.plugin && w.plugin.constructor && w.plugin.constructor.name === name); } - /** - * Returns plugins that match provided type. - * - * @example - * helpers.getPluginsByType(config, webpack.optimize.CommonsChunkPlugin) - * @param {object} config - [webpack config](https://webpack.js.org/configuration/#options). - * @param {any} type - type of plugin. - * @returns {PluginWrapper[]} - * - * @memberof WebpackConfigHelpers - */ + /** + * Returns plugins that match provided type. + * + * @example + * helpers.getPluginsByType(config, webpack.optimize.CommonsChunkPlugin) + * @param {object} config - [webpack config](https://webpack.js.org/configuration/#options). + * @param {any} type - type of plugin. + * @returns {PluginWrapper[]} + * + * @memberof WebpackConfigHelpers + */ getPluginsByType(config, type) { return this.getPlugins(config) .filter(w => w.plugin instanceof type); } - /** - * Sets template used by HtmlWebpackPlugin. - * - * @param {object} config - [webpack config](https://webpack.js.org/configuration/#options). - * @param {string} template - template path. See [HtmlWebpackPlugin docs](https://github.com/jantimon/html-webpack-plugin/blob/master/docs/template-option.md). - * - * @memberof WebpackConfigHelpers - */ + /** + * Sets template used by HtmlWebpackPlugin. + * + * @param {object} config - [webpack config](https://webpack.js.org/configuration/#options). + * @param {string} template - template path. See [HtmlWebpackPlugin docs](https://github.com/jantimon/html-webpack-plugin/blob/master/docs/template-option.md). + * + * @memberof WebpackConfigHelpers + */ setHtmlTemplate(config, template) { let isPath; try { diff --git a/src/lib/webpack/webpack-base-config.js b/src/lib/webpack/webpack-base-config.js index ccb356fd1..b46be68dc 100644 --- a/src/lib/webpack/webpack-base-config.js +++ b/src/lib/webpack/webpack-base-config.js @@ -14,6 +14,7 @@ import autoprefixer from 'autoprefixer'; import ProgressBarPlugin from 'progress-bar-webpack-plugin'; import ReplacePlugin from 'webpack-plugin-replace'; import requireRelative from 'require-relative'; +import createBabelConfig from '../babel-config'; export function exists(file) { try { @@ -33,9 +34,9 @@ readJson.cache = {}; // attempt to resolve a dependency, giving $CWD/node_modules priority: function resolveDep(dep, cwd) { - try { return requireRelative.resolve(dep, cwd || process.cwd()); } catch (e) {} - try { return require.resolve(dep); } catch (e) {} - return dep; + try { return requireRelative.resolve(dep, cwd || process.cwd()); } catch (e) {} + try { return require.resolve(dep); } catch (e) {} + return dep; } export default (env) => { @@ -48,6 +49,7 @@ export default (env) => { env.manifest = readJson(src('manifest.json')) || {}; env.pkg = readJson(resolve(cwd, 'package.json')) || {}; + let babelrc = readJson(resolve(cwd, '.babelrc')) || {}; let browsers = env.pkg.browserslist || ['> 1%', 'last 2 versions', 'IE >= 9']; return group([ @@ -86,12 +88,10 @@ export default (env) => { enforce: 'pre', test: /\.jsx?$/, loader: 'babel-loader', - options: { - babelrc: true, - presets: [ - [resolve(__dirname, '../babel-config'), { browsers }] - ] - } + options: Object.assign( + createBabelConfig(env, { browsers }), + babelrc // intentionall overwrite our settings + ) } ] } @@ -255,7 +255,7 @@ export default (env) => { ].filter(Boolean)); }; -const development = () => group([]); +const development = () => group([]); const production = () => addPlugins([ new webpack.HashedModuleIdsPlugin(), @@ -313,7 +313,7 @@ const production = () => addPlugins([ export function helpers(env) { return { - isProd: env && env.production, + isProd: env && env.production, cwd: env.cwd = resolve(env.cwd || process.cwd()), src: dir => resolve(env.cwd, env.src || 'src', dir) }; diff --git a/tests/build.snapshot.js b/tests/build.snapshot.js index 30eb85049..a289ec1ac 100644 --- a/tests/build.snapshot.js +++ b/tests/build.snapshot.js @@ -66,16 +66,16 @@ export default { 'bundle.js': { size: 18460 }, 'bundle.js.map': { size: 101500 }, 'route-home.chunk.*.js': { size: 1020 }, - 'route-home.chunk.*.js.map': { size: 4283 }, + 'route-home.chunk.*.js.map': { size: 4977 }, 'route-profile.chunk.*.js': { size: 1660 }, - 'route-profile.chunk.*.js.map': { size: 7504 }, + 'route-profile.chunk.*.js.map': { size: 8607 }, 'polyfills.js.map': { size: 31750 }, 'index.html': { size: 870 }, 'style.css': { size: 1065 }, 'style.css.map': { size: 2246 }, 'ssr-build': { 'ssr-bundle.js': { size: 18960 }, - 'ssr-bundle.js.map': { size: 91773 }, + 'ssr-bundle.js.map': { size: 97403 }, 'style.css': { size: 1065 }, 'style.css.map': { size: 2250 }, } @@ -85,16 +85,16 @@ export default { 'bundle.js': { size: 19300 }, 'bundle.js.map': { size: 105590 }, 'route-home.chunk.*.js': { size: 1000 }, - 'route-home.chunk.*.js.map': { size: 4285 }, + 'route-home.chunk.*.js.map': { size: 4981 }, 'route-profile.chunk.*.js': { size: 1650 }, - 'route-profile.chunk.*.js.map': { size: 7507 }, + 'route-profile.chunk.*.js.map': { size: 8609 }, 'polyfills.js.map': { size: 31800 }, 'index.html': { size: 850 }, 'style.css': { size: 1065 }, 'style.css.map': { size: 2345 }, 'ssr-build': { 'ssr-bundle.js': { size: 19820 }, - 'ssr-bundle.js.map': { size: 95581 }, + 'ssr-bundle.js.map': { size: 101502 }, 'style.css': { size: 1065 }, 'style.css.map': { size: 2345 }, } diff --git a/tests/subjects/custom-babelrc/.babelrc b/tests/subjects/custom-babelrc/.babelrc index fa5b8e976..d30f308f0 100644 --- a/tests/subjects/custom-babelrc/.babelrc +++ b/tests/subjects/custom-babelrc/.babelrc @@ -1,6 +1,7 @@ { "plugins": [ "transform-regenerator", + ["transform-react-jsx", { "pragma": "h" }], ["transform-runtime", { "helpers": false, "polyfill": false, diff --git a/tests/subjects/custom-babelrc/index.js b/tests/subjects/custom-babelrc/index.js index 0f12696de..c1c4fc867 100644 --- a/tests/subjects/custom-babelrc/index.js +++ b/tests/subjects/custom-babelrc/index.js @@ -1,4 +1,4 @@ -import { Component } from 'preact'; +import { h, Component } from 'preact'; const delay = t => new Promise(r => setTimeout(r, t));