diff --git a/packages/cli/package.json b/packages/cli/package.json index ae58aafc71..03eef30031 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -109,7 +109,7 @@ "typescript": "^4.0.3", "url-loader": "^4.1.0", "util": "^0.12.3", - "webpack": "^5.36.2", + "webpack": "^5.48.0", "webpack-dev-server": "4.0.0-rc.0", "webpack-node-externals": "^3.0.0", "yaml": "^1.10.0", diff --git a/packages/cli/src/lib/bundler/backend.ts b/packages/cli/src/lib/bundler/backend.ts index bd4ab42098..567fc3476a 100644 --- a/packages/cli/src/lib/bundler/backend.ts +++ b/packages/cli/src/lib/bundler/backend.ts @@ -28,6 +28,7 @@ export async function serveBackend(options: BackendServeOptions) { const compiler = webpack(config, (err: Error | undefined) => { if (err) { + console.log('here'); console.error(err); } else console.log('Build succeeded'); }); diff --git a/packages/cli/src/lib/bundler/config.ts b/packages/cli/src/lib/bundler/config.ts index 8c2b3ce95e..f749c70ed2 100644 --- a/packages/cli/src/lib/bundler/config.ts +++ b/packages/cli/src/lib/bundler/config.ts @@ -98,10 +98,9 @@ export async function createConfig( if (checksEnabled) { plugins.push( new ForkTsCheckerWebpackPlugin({ - typescript: { - configFile: paths.targetTsConfig, - }, - eslint: { + typescript: paths.targetTsConfig, + eslint: true, + eslintOptions: { files: ['**', '!**/__tests__/**', '!**/?(*.)(spec|test).*'], options: { parserOptions: { @@ -170,9 +169,6 @@ export async function createConfig( performance: { hints: false, // we check the gzip size instead }, - // Workaround for hot module reloads not working, will be fixed in webpack-dev-server v4 - // https://github.com/webpack/webpack-dev-server/issues/2758 - target: 'web', devtool: isDev ? 'eval-cheap-module-source-map' : 'source-map', context: paths.targetPath, entry: [require.resolve('react-hot-loader/patch'), paths.targetEntry], @@ -218,7 +214,7 @@ export async function createConfig( : 'static/[name].[chunkhash:8].chunk.js', ...(isDev ? { - devtoolModuleFilenameTemplate: info => + devtoolModuleFilenameTemplate: (info: any) => `file:///${resolvePath(info.absoluteResourcePath).replace( /\\/g, '/', @@ -309,7 +305,7 @@ export async function createBackendConfig( : '[name].[chunkhash:8].chunk.js', ...(isDev ? { - devtoolModuleFilenameTemplate: info => + devtoolModuleFilenameTemplate: (info: any) => `file:///${resolvePath(info.absoluteResourcePath).replace( /\\/g, '/', @@ -326,10 +322,9 @@ export async function createBackendConfig( ...(checksEnabled ? [ new ForkTsCheckerWebpackPlugin({ - typescript: { - configFile: paths.targetTsConfig, - }, - eslint: { + typescript: paths.targetTsConfig, + eslint: true, + eslintOptions: { files: ['**', '!**/__tests__/**', '!**/?(*.)(spec|test).*'], options: { parserOptions: { diff --git a/packages/cli/src/types.d.ts b/packages/cli/src/types.d.ts index 07684bc15a..0ca023def7 100644 --- a/packages/cli/src/types.d.ts +++ b/packages/cli/src/types.d.ts @@ -260,3 +260,402 @@ declare module 'webpack-node-externals' { } } } + +declare module 'webpack-dev-server' { + import webpack = require('webpack'); + import httpProxyMiddleware = require('http-proxy-middleware'); + import express = require('express'); + import serveStatic = require('serve-static'); + import https = require('https'); + import http = require('http'); + import connectHistoryApiFallback = require('connect-history-api-fallback'); + + interface ListeningApp { + address(): { port?: number | undefined }; + } + + interface ProxyConfigMap { + [url: string]: string | httpProxyMiddleware.Options; + } + + type ProxyConfigArrayItem = { + path?: string | string[] | undefined; + context?: string | string[] | httpProxyMiddleware.Filter | undefined; + } & httpProxyMiddleware.Options; + + type ProxyConfigArray = ProxyConfigArrayItem[]; + + interface Configuration { + /** + * Provides the ability to execute custom middleware after all other + * middleware internally within the server. + */ + after?: + | (( + app: express.Application, + server: WebpackDevServer, + compiler: webpack.Compiler, + ) => void) + | undefined; + /** + * This option allows you to whitelist services that are allowed to + * access the dev server. + */ + allowedHosts?: string[] | undefined; + /** + * Provides the ability to execute custom middleware prior to all + * other middleware internally within the server. + */ + before?: + | (( + app: express.Application, + server: WebpackDevServer, + compiler: webpack.Compiler, + ) => void) + | undefined; + /** + * This option broadcasts the server via ZeroConf networking on start. + */ + bonjour?: boolean | undefined; + /** + * When using inline mode, the console in your DevTools will show you + * messages e.g. before reloading, before an error or when Hot Module + * Replacement is enabled. This may be too verbose. + * + * 'none' and 'warning' are going to be deprecated at the next major + * version. + */ + clientLogLevel?: + | 'silent' + | 'trace' + | 'debug' + | 'info' + | 'warn' + | 'error' + | 'none' + | 'warning' + | undefined; + /** + * Enable gzip compression for everything served. + */ + compress?: boolean | undefined; + /** + * Tell the server where to serve content from. This is only necessary + * if you want to serve static files. devServer.publicPath will be used + * to determine where the bundles should be served from, and takes + * precedence. + */ + contentBase?: boolean | string | string[] | number | undefined; + /** + * Tell the server at what URL to serve `devServer.contentBase`. + * If there was a file `assets/manifest.json`, + * it would be served at `/serve-content-base-at-this-url/manifest.json` + */ + contentBasePublicPath?: string | string[] | undefined; + /** + * When set to true this option bypasses host checking. THIS IS NOT + * RECOMMENDED as apps that do not check the host are vulnerable to DNS + * rebinding attacks. + */ + disableHostCheck?: boolean | undefined; + /** + * This option lets you reduce the compilations in lazy mode. + * By default in lazy mode, every request results in a new compilation. + * With filename, it's possible to only compile when a certain file is requested. + */ + filename?: string | undefined; + /** Adds headers to all responses. */ + headers?: + | { + [key: string]: string; + } + | undefined; + /** + * When using the HTML5 History API, the index.html page will likely + * have to be served in place of any 404 responses. + */ + historyApiFallback?: + | boolean + | connectHistoryApiFallback.Options + | undefined; + /** + * Specify a host to use. By default this is localhost. + */ + host?: string | undefined; + /** + * Enable webpack's Hot Module Replacement feature. + * Note that webpack.HotModuleReplacementPlugin is required to fully + * enable HMR. If webpack or webpack-dev-server are launched with the + * --hot option, this plugin will be added automatically, so you may + * not need to add this to your webpack.config.js. + */ + hot?: boolean | undefined; + /** + * Enables Hot Module Replacement (see devServer.hot) without page + * refresh as fallback in case of build failures. + */ + hotOnly?: boolean | undefined; + /** + * Serve over HTTP/2 using spdy. This option is ignored for Node 10.0.0 + * and above, as spdy is broken for those versions. The dev server will + * migrate over to Node's built-in HTTP/2 once Express supports it. + */ + http2?: boolean | undefined; + /** + * By default dev-server will be served over HTTP. It can optionally be + * served over HTTP/2 with HTTPS. + */ + https?: boolean | https.ServerOptions | undefined; + /** + * The filename that is considered the index file. + */ + index?: string | undefined; + /** + * Tells devServer to inject a client. Setting devServer.injectClient + * to true will result in always injecting a client. It is possible to + * provide a function to inject conditionally + */ + injectClient?: + | boolean + | ((compilerConfig: webpack.Compiler) => boolean) + | undefined; + /** + * Tells devServer to inject a Hot Module Replacement. Setting + * devServer.injectHot to true will result in always injecting. It is + * possible to provide a function to inject conditionally + */ + injectHot?: + | boolean + | ((compilerConfig: webpack.Compiler) => boolean) + | undefined; + /** + * Toggle between the dev-server's two different modes. By default the + * application will be served with inline mode enabled. This means + * that a script will be inserted in your bundle to take care of live + * reloading, and build messages will appear in the browser console. + */ + inline?: boolean | undefined; + /** + * When lazy is enabled, the dev-server will only compile the bundle + * when it gets requested. This means that webpack will not watch any + * file changes. + */ + lazy?: boolean | undefined; + /** + * By default, the dev-server will reload/refresh the page when file + * changes are detected. devServer.hot option must be disabled or + * devServer.watchContentBase option must be enabled in order for + * liveReload to take effect. Disable devServer.liveReload by setting + * it to false + */ + liveReload?: boolean | undefined; + /** + * The object is passed to the underlying webpack-dev-middleware. See + * [documentation](https://github.com/webpack/webpack-dev-middleware#mimetypes) + * for usage notes. + */ + mimeTypes?: + | { + [key: string]: string[]; + } + | { + typeMap?: + | ({ + [key: string]: string[]; + } & { + force: boolean; + }) + | undefined; + } + | undefined; + /** + * With noInfo enabled, messages like the webpack bundle information + * that is shown when starting up and after each save,will be hidden. + * Errors and warnings will still be shown. + */ + noInfo?: boolean | undefined; + /** + * Provides an option to execute a custom function when + * webpack-dev-server starts listening for connections on a port. + */ + onListening?: ((server: WebpackDevServer) => void) | undefined; + /** When open is enabled, the dev server will open the browser. */ + open?: boolean | string | object | undefined; + /** Specify a page to navigate to when opening the browser. */ + openPage?: string | string[] | undefined; + /** + * Shows a full-screen overlay in the browser when there are compiler + * errors or warnings. Disabled by default. + */ + overlay?: + | boolean + | { + warnings?: boolean | undefined; + errors?: boolean | undefined; + } + | undefined; + /** + * When used via the CLI, a path to an SSL .pfx file. If used in + * options, it should be the bytestream of the .pfx file. + */ + pfx?: string | undefined; + /** The passphrase to a SSL PFX file. */ + pfxPassphrase?: string | undefined; + /** Specify a port number to listen for requests on. */ + port?: number | undefined; + /** + * Proxying some URLs can be useful when you have a separate API + * backend development server and you want to send API requests on the + * same domain. + * + * The dev-server makes use of the powerful http-proxy-middleware + * package. Check out its + * [documentation](https://github.com/chimurai/http-proxy-middleware#options) + * for more advanced usages. Note that some of http-proxy-middleware's + * features do not require a target key, e.g. its router feature, but + * you will still need to include a target key in your config here, + * otherwise webpack-dev-server won't pass it along to + * http-proxy-middleware). + */ + proxy?: ProxyConfigMap | ProxyConfigArray | undefined; + /** + * When using inline mode and you're proxying dev-server, the inline + * client script does not always know where to connect to. It will try + * to guess the URL of the server based on window.location, but if that + * fails you'll need to use this. + */ + public?: string | undefined; + /** + * The bundled files will be available in the browser under this path. + * default is '/' + */ + publicPath?: string | undefined; + /** + * With quiet enabled, nothing except the initial startup information + * will be written to the console. This also means that errors or + * warnings from webpack are not visible. + */ + quiet?: boolean | undefined; + /** + * Tells dev-server to use serveIndex middleware when enabled. + * + * serveIndex middleware generates directory listings on viewing + * directories that don't have an index.html file. + */ + serveIndex?: boolean | undefined; + /** + * @deprecated This option is deprecated in favor of devServer.before + * and will be removed in v3.0.0. Here you can access the Express app + * object and add your own custom middleware to it. + */ + setup?: + | ((app: express.Application, server: WebpackDevServer) => void) + | undefined; + /** The Unix socket to listen to (instead of a host). */ + socket?: string | undefined; + /** + * Tells clients connected to devServer to use provided socket host. + */ + sockHost?: string | undefined; + /** + * The path at which to connect to the reloading socket. Default is + * '/sockjs-node' + */ + sockPath?: string | undefined; + /** + * Tells clients connected to devServer to use provided socket port. + */ + sockPort?: string | number | undefined; + /** + * It is possible to configure advanced options for serving static + * files from contentBase. + * + * This only works when using devServer.contentBase as a string. + */ + staticOptions?: serveStatic.ServeStaticOptions | undefined; + /** + * This option lets you precisely control what bundle information gets + * displayed. This can be a nice middle ground if you want some bundle + * information, but not all of it. + */ + stats?: webpack.Configuration['stats'] | undefined; + /** + * transportMode is an experimental option, meaning its usage could + * potentially change without warning. + * + * Providing a string to devServer.transportMode is a shortcut to + * setting both devServer.transportMode.client and + * devServer.transportMode.server to the given string value. + * + * This option allows us either to choose the current devServer + * transport mode for client/server individually or to provide custom + * client/server implementation. This allows to specify how browser or + * other client communicates with the devServer. + * + * The current default mode is 'sockjs'. This mode uses SockJS-node as + * a server, and SockJS-client on the client. + * + * 'ws' mode will become the default mode in the next major devServer + * version. This mode uses ws as a server, and native WebSockets on the + * client. + */ + transportMode?: + | 'sockjs' + | 'ws' + | { + client: object; + server: 'ws'; + } + | { + client: 'ws'; + server: object; + } + | { + client: object; + server: object; + } + | undefined; + /** This option lets the browser open with your local IP. */ + useLocalIp?: boolean | undefined; + /** + * Tell the server to watch the files served by the + * devServer.contentBase option. File changes will trigger a full page + * reload. + */ + watchContentBase?: boolean | undefined; + /** Control options related to watching the files. */ + watchOptions?: webpack.Configuration['watchOptions'] | undefined; + /** Tells devServer to write generated assets to the disk. */ + writeToDisk?: boolean | ((filePath: string) => boolean) | undefined; + } + + export class WebpackDevServer { + listeningApp: WebpackDevServer.ListeningApp; + sockets: NodeJS.EventEmitter[]; + + constructor( + webpack: webpack.Compiler | webpack.MultiCompiler, + config?: WebpackDevServer.Configuration, + ); + + static addDevServerEntrypoints( + webpackOptions: webpack.Configuration | webpack.Configuration[], + config: WebpackDevServer.Configuration, + listeningApp?: WebpackDevServer.ListeningApp, + ): void; + + listen( + port: number, + hostname: string, + callback?: (error?: Error) => void, + ): http.Server; + + listen(port: number, callback?: (error?: Error) => void): http.Server; + + close(callback?: () => void): void; + + sockWrite(sockets: NodeJS.EventEmitter[], type: string, data?: any): void; + } + + export = WebpackDevServer; +} diff --git a/yarn.lock b/yarn.lock index d91285da03..a1adaad977 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7419,6 +7419,11 @@ acorn-globals@^6.0.0: acorn "^7.1.1" acorn-walk "^7.1.1" +acorn-import-assertions@^1.7.6: + version "1.7.6" + resolved "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.7.6.tgz#580e3ffcae6770eebeec76c3b9723201e9d01f78" + integrity sha512-FlVvVFA1TX6l3lp8VjDnYYq7R1nyW6x3svAt4nDgrWQ9SBaSh9CnbwgSUTasgfNfOG5HlM1ehugCvM+hjo56LA== + acorn-jsx@^5.3.1: version "5.3.1" resolved "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.1.tgz#fc8661e11b7ac1539c47dbfea2e72b3af34d267b" @@ -26672,6 +26677,11 @@ webpack-sources@^3.0.1: resolved "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.0.2.tgz#29942415daf201a06278f8e2b92e44e564a9288e" integrity sha512-XQ6aGLmqoxZtmpbgwySGhYLNFav1W6+qgMWPGgn6qScxfGrQgMdigkUqZXQ7oB0ydUrvfs9RRyHaSfV153K8Xg== +webpack-sources@^3.2.0: + version "3.2.0" + resolved "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.0.tgz#b16973bcf844ebcdb3afde32eda1c04d0b90f89d" + integrity sha512-fahN08Et7P9trej8xz/Z7eRu8ltyiygEo/hnRi9KqBUs80KeDcnf96ZJo++ewWd84fEf3xSX9bp4ZS9hbw0OBw== + webpack-virtual-modules@^0.2.2: version "0.2.2" resolved "https://registry.npmjs.org/webpack-virtual-modules/-/webpack-virtual-modules-0.2.2.tgz#20863dc3cb6bb2104729fff951fbe14b18bd0299" @@ -26708,7 +26718,7 @@ webpack@^4.44.2: watchpack "^1.7.4" webpack-sources "^1.4.1" -webpack@^5, webpack@^5.36.2: +webpack@^5: version "5.47.0" resolved "https://registry.npmjs.org/webpack/-/webpack-5.47.0.tgz#3c13862b5d7b428792bfe76c5f67a0f43ba685f8" integrity sha512-soKLGwcUM1R3YEbJhJNiZzy7T43TnI7ENda/ywfDp9G1mDlDTpO+qfc8I5b0AzMr9xM3jyvQ0n7ctJyiXuXW6Q== @@ -26737,6 +26747,36 @@ webpack@^5, webpack@^5.36.2: watchpack "^2.2.0" webpack-sources "^3.0.1" +webpack@^5.48.0: + version "5.48.0" + resolved "https://registry.npmjs.org/webpack/-/webpack-5.48.0.tgz#06180fef9767a6fd066889559a4c4d49bee19b83" + integrity sha512-CGe+nfbHrYzbk7SKoYITCgN3LRAG0yVddjNUecz9uugo1QtYdiyrVD8nP1PhkNqPfdxC2hknmmKpP355Epyn6A== + dependencies: + "@types/eslint-scope" "^3.7.0" + "@types/estree" "^0.0.50" + "@webassemblyjs/ast" "1.11.1" + "@webassemblyjs/wasm-edit" "1.11.1" + "@webassemblyjs/wasm-parser" "1.11.1" + acorn "^8.4.1" + acorn-import-assertions "^1.7.6" + browserslist "^4.14.5" + chrome-trace-event "^1.0.2" + enhanced-resolve "^5.8.0" + es-module-lexer "^0.7.1" + eslint-scope "5.1.1" + events "^3.2.0" + glob-to-regexp "^0.4.1" + graceful-fs "^4.2.4" + json-parse-better-errors "^1.0.2" + loader-runner "^4.2.0" + mime-types "^2.1.27" + neo-async "^2.6.2" + schema-utils "^3.1.0" + tapable "^2.1.1" + terser-webpack-plugin "^5.1.3" + watchpack "^2.2.0" + webpack-sources "^3.2.0" + websocket-driver@>=0.5.1: version "0.7.3" resolved "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.3.tgz#a2d4e0d4f4f116f1e6297eba58b05d430100e9f9" @@ -27036,7 +27076,7 @@ write-pkg@^4.0.0: type-fest "^0.4.1" write-json-file "^3.2.0" -ws@7.4.5, ws@^7.4.6: +ws@7.4.5, ws@^7.4.6, ws@^7.5.3: version "7.5.3" resolved "https://registry.npmjs.org/ws/-/ws-7.5.3.tgz#160835b63c7d97bfab418fc1b8a9fced2ac01a74" integrity sha512-kQ/dHIzuLrS6Je9+uv81ueZomEwH0qVYstcAQ4/Z93K8zeko9gtAbttJWzoC5ukqXY1PpoouV3+VSOqEAFt5wg== @@ -27065,11 +27105,6 @@ ws@^7.2.3, ws@^7.3.1: resolved "https://registry.npmjs.org/ws/-/ws-7.3.1.tgz#d0547bf67f7ce4f12a72dfe31262c68d7dc551c8" integrity sha512-D3RuNkynyHmEJIpD2qrgVkc9DQ23OrN/moAwZX4L8DfvszsJxpjQuUq3LMx6HoYji9fbIOBY18XWBsAux1ZZUA== -ws@^7.5.3: - version "7.5.3" - resolved "https://registry.npmjs.org/ws/-/ws-7.5.3.tgz#160835b63c7d97bfab418fc1b8a9fced2ac01a74" - integrity sha512-kQ/dHIzuLrS6Je9+uv81ueZomEwH0qVYstcAQ4/Z93K8zeko9gtAbttJWzoC5ukqXY1PpoouV3+VSOqEAFt5wg== - xcase@^2.0.1: version "2.0.1" resolved "https://registry.npmjs.org/xcase/-/xcase-2.0.1.tgz#c7fa72caa0f440db78fd5673432038ac984450b9"