1+ const { merge } = require ( "webpack-merge" ) ;
2+ const { configs } = require ( "@nativescript/webpack/dist/configuration" ) ;
3+ const { getPlatformName } = require ( "@nativescript/webpack/dist/helpers/platform" ) ;
4+ const { env : _env } = require ( "@nativescript/webpack" ) ;
5+
16/**
2- * @see https://github.com/NativeScript/NativeScript/tree/feat/ns7-finishing-touches/packages/webpack/templates
3- * @see https://github.com/NativeScript/NativeScript/pull/8801/files
7+ * @param config {import("webpack-chain").Config}
8+ * @param env {import("@nativescript/webpack").IWebpackEnv }
9+ * @returns {import("webpack-chain").Config }
410 */
5- const webpackConfig = require ( "./webpack.typescript" ) ;
6- const webpack = require ( "webpack" ) ;
7- const ReactRefreshWebpackPlugin = require ( '@pmmmwh/react-refresh-webpack-plugin' ) ;
11+ module . exports = function ( config , env = _env ) {
12+ configs . base ( config , env ) ;
13+
14+ const platform = getPlatformName ( ) ;
15+ const mode = env . production ? 'production' : 'development' ;
16+ const production = mode === 'production' ;
17+
18+ // todo: use env
19+ let isAnySourceMapEnabled = true ;
820
9- module . exports = ( env ) => {
10- env = env || { } ;
11- const hmr = env . hmr ;
12- const production = env . production ;
13- const isAnySourceMapEnabled = ! ! env . sourceMap || ! ! env . hiddenSourceMap ;
21+ config . resolve . extensions . prepend ( '.tsx' ) . prepend ( `.${ platform } .tsx` ) ;
22+ config . resolve . alias . set ( 'react-dom' , 'react-nativescript' ) ;
1423
15- const baseConfig = webpackConfig ( env ) ;
24+ config . module
25+ . rule ( 'ts' )
26+ . test ( [ ...config . module . rule ( 'ts' ) . get ( 'test' ) , / \. t s x $ / ] ) ;
1627
17- /** Find the rule for transpiling ts files ("ts-loader"), and modify it to test for .tsx files too. */
18- const tsxRule = baseConfig . module . rules . find ( rule => rule . use && rule . use . loader === "ts-loader" ) ;
19- tsxRule . test = / \. ( t s | t s x ) $ / ;
20- tsxRule . use = [
21- /**
22- * Add React Refresh HMR support.
23- * @see https://github.com/pmmmwh/react-refresh-webpack-plugin/blob/55028c6355b31e697e21bf3e9a48613a7b94bee7/examples/typescript-without-babel/webpack.config.js#L18-L21
24- */
25- hmr && ! production && {
26- loader : "babel-loader" ,
27- options : {
28- sourceMaps : isAnySourceMapEnabled ? "inline" : false ,
29- babelrc : false ,
30- plugins : [ 'react-refresh/babel' ]
31- }
32- } ,
33- tsxRule . use ,
34- ] . filter ( Boolean ) ;
28+ config . plugin ( 'DefinePlugin' ) . tap ( ( args ) => {
29+ args [ 0 ] = merge ( args [ 0 ] , {
30+ /** For various libraries in the React ecosystem. */
31+ __TEST__ : false ,
32+ /**
33+ * Primarily for React Fast Refresh plugin, but technically the allowHmrInProduction option could be used instead.
34+ * Worth including anyway, as there are plenty of Node libraries that use this flag.
35+ */
36+ 'process.env.NODE_ENV' : JSON . stringify ( mode ) ,
37+ } ) ;
3538
36- /**
37- * Modify "nativescript-dev-webpack/hmr/hot-loader" to test for .tsx files
38- * (and also js files, which it should have been doing to begin with!)
39- */
40- const nativeScriptDevWebpackHotLoader = baseConfig . module . rules . find ( rule =>
41- rule . use === "@nativescript/webpack/hmr/hot-loader"
42- ) ;
43- nativeScriptDevWebpackHotLoader . test = / \. ( t s | t s x | j s | c s s | s c s s | h t m l | x m l ) $ / ;
39+ return args ;
40+ } ) ;
4441
45- /** We don't officially support JSX. Makes the webpack config rather more complicated to set up. */
46- baseConfig . resolve . extensions = [ ".tsx" , ...baseConfig . resolve . extensions ] ;
47- baseConfig . resolve . alias [ "react-dom" ] = "react-nativescript" ;
42+ // todo: env flag to forceEnable?
43+ config . when ( env . hmr && ! production , ( config ) => {
44+ config . module
45+ . rule ( 'ts' )
46+ . use ( 'babel-loader|react-refresh' )
47+ . loader ( 'babel-loader' )
48+ . before ( 'ts-loader' )
49+ . options ( {
50+ sourceMaps : isAnySourceMapEnabled ? 'inline' : false ,
51+ babelrc : false ,
52+ plugins : [ 'react-refresh/babel' ] ,
53+ } ) ;
4854
49- /** Augment NativeScript's existing DefinePlugin definitions with a few more of our own. */
50- const existingDefinePlugin = baseConfig . plugins . find ( plugin =>
51- plugin && plugin . constructor && plugin . constructor . name === "DefinePlugin"
52- ) ;
53- baseConfig . plugins . splice (
54- baseConfig . plugins . indexOf ( existingDefinePlugin ) ,
55- 1 ,
56- new webpack . DefinePlugin ( {
57- ...existingDefinePlugin . definitions ,
58- /** For various libraries in the React ecosystem. */
59- "__DEV__" : production ? "false" : "true" ,
60- "__TEST__" : "false" ,
61- /**
62- * Primarily for React Fast Refresh plugin, but technically the allowHmrInProduction option could be used instead.
63- * Worth including anyway, as there are plenty of Node libraries that use this flag.
64- */
65- "process.env.NODE_ENV" : JSON . stringify ( production ? "production" : "development" ) ,
66- } ) ,
67- ) ;
55+ config
56+ . plugin ( 'ReactRefreshPlugin' )
57+ . use ( require ( '@pmmmwh/react-refresh-webpack-plugin' ) , [
58+ {
59+ /**
60+ * Maybe one day we'll implement an Error Overlay, but the work involved is too daunting for now.
61+ * @see https://github.com/pmmmwh/react-refresh-webpack-plugin/issues/79#issuecomment-644324557
62+ */
63+ overlay : false ,
64+ /**
65+ * If you (temporarily) want to enable HMR on a production build:
66+ * 1) Set `forceEnable` to `true`
67+ * 2) Remove the `!production` condition on `tsxRule` to ensure that babel-loader gets used.
68+ */
69+ forceEnable : false ,
70+ } ,
71+ ] ) ;
72+ } ) ;
6873
69- if ( hmr && ! production ) {
70- baseConfig . plugins . push ( new ReactRefreshWebpackPlugin ( {
71- /**
72- * Maybe one day we'll implement an Error Overlay, but the work involved is too daunting for now.
73- * @see https://github.com/pmmmwh/react-refresh-webpack-plugin/issues/79#issuecomment-644324557
74- */
75- overlay : false ,
76- /**
77- * If you (temporarily) want to enable HMR on a production build:
78- * 1) Set `forceEnable` to `true`
79- * 2) Remove the `!production` condition on `tsxRule` to ensure that babel-loader gets used.
80- */
81- forceEnable : false ,
82- } ) ) ;
83- } else {
84- baseConfig . plugins = baseConfig . plugins . filter ( p => ! ( p && p . constructor && p . constructor . name === "HotModuleReplacementPlugin" ) ) ;
85- }
74+ console . log ( `Webpack 5 config:` , config ) ;
8675
87- return baseConfig ;
88- } ;
76+ return config ;
77+ }
0 commit comments