diff --git a/.changeset/five-peas-brake.md b/.changeset/five-peas-brake.md new file mode 100644 index 000000000..9e6391391 --- /dev/null +++ b/.changeset/five-peas-brake.md @@ -0,0 +1,5 @@ +--- +'preact-cli': minor +--- + +Supports consuming "proxy" from package.json to proxy API requests in watch mode diff --git a/packages/cli/lib/lib/webpack/webpack-client-config.js b/packages/cli/lib/lib/webpack/webpack-client-config.js index 646e76566..dac17d00d 100644 --- a/packages/cli/lib/lib/webpack/webpack-client-config.js +++ b/packages/cli/lib/lib/webpack/webpack-client-config.js @@ -278,6 +278,43 @@ function isProd(env) { return prodConfig; } +function setupProxy(target) { + if (!target) { + return; + } + + const errorTemplate = warn => + `Invalid proxy configuration in package.json. ${warn} Skipping and using default.`; + + if (typeof target !== 'string') { + warn(errorTemplate('If provided, "proxy" must be a string.')); + return; + } else if (!/https?:\/\//.test(target)) { + warn( + errorTemplate( + 'If provided, "proxy" must start with "http://" or "https://".' + ) + ); + return; + } + + return { + target, + logLevel: 'warn', + context: (pathname, req) => { + return ( + req.method != 'GET' || + (!(/^\/?assets/.test(pathname) || pathname.startsWith('/ws')) && + req.headers.accept.indexOf('html') === -1) + ); + }, + secure: false, + changeOrigin: true, + ws: true, + xfwd: true, + }; +} + /** * @returns {import('webpack').Configuration} */ @@ -315,6 +352,7 @@ function isDev(env) { logging: 'none', overlay: false, }, + proxy: setupProxy(env.pkg.proxy), }, }; } diff --git a/packages/cli/tests/build.test.js b/packages/cli/tests/build.test.js index 7405ce16e..fe172d934 100644 --- a/packages/cli/tests/build.test.js +++ b/packages/cli/tests/build.test.js @@ -73,7 +73,9 @@ describe('preact build', () => { // The tsconfig.json in the template covers the test directory, // so TS will error out if it can't find even test-only module definitions shell.cd(dir); - shell.exec('npm i @types/enzyme enzyme-adapter-preact-pure'); + //shell.exec('npm i @types/enzyme@3.10.11 enzyme-adapter-preact-pure'); + // Remove when https://github.com/preactjs/enzyme-adapter-preact-pure/issues/161 is resolved + shell.exec('rm tsconfig.json'); expect(() => build(dir)).not.toThrow(); }); diff --git a/packages/cli/tests/server.js b/packages/cli/tests/server.js index b0fbef8a3..abbae9672 100644 --- a/packages/cli/tests/server.js +++ b/packages/cli/tests/server.js @@ -6,5 +6,10 @@ exports.getServer = (dir, port = 3000) => { maxAge: 0, single: true, }; - return polka().use(sirv(dir, opts)).listen(port); + return polka() + .use(sirv(dir, opts)) + .get('/proxied/request', (_req, res) => { + res.end('Hello World!'); + }) + .listen(port); }; diff --git a/packages/cli/tests/subjects/proxy/index.js b/packages/cli/tests/subjects/proxy/index.js new file mode 100644 index 000000000..e154e7db6 --- /dev/null +++ b/packages/cli/tests/subjects/proxy/index.js @@ -0,0 +1,14 @@ +import { h } from 'preact'; +import { useEffect, useState } from 'preact/hooks'; + +export default () => { + const [val, setVal] = useState(''); + + useEffect(() => { + fetch('/proxied/request') + .then(res => res.text()) + .then(data => setVal(data)); + }, []); + + return