mirror of
https://github.com/NativeScript/NativeScript.git
synced 2025-11-05 13:26:48 +08:00
chore: HMRRuntime injection (wip)
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
#!/bin/env node
|
||||
#!/usr/bin/env node
|
||||
|
||||
import { redBright, green, greenBright } from 'chalk';
|
||||
import { program } from 'commander';
|
||||
|
||||
@@ -81,7 +81,7 @@ export default function (config: Config, env: IWebpackEnv = _env): Config {
|
||||
|
||||
config.watchOptions({
|
||||
ignored: [
|
||||
`${getProjectFilePath('platforms')}/platforms/**`,
|
||||
`${getProjectFilePath('platforms')}/**`,
|
||||
`${env.appResourcesPath ?? getProjectFilePath('App_Resources')}/**`
|
||||
]
|
||||
})
|
||||
@@ -137,6 +137,15 @@ export default function (config: Config, env: IWebpackEnv = _env): Config {
|
||||
// resolve symlinks
|
||||
config.resolve.symlinks(true);
|
||||
|
||||
config.module.rule('bundle')
|
||||
.enforce('post')
|
||||
.test(entryPath)
|
||||
.use('nativescript-hot-loader')
|
||||
.loader('nativescript-hot-loader')
|
||||
.options({
|
||||
injectHMRRuntime: true
|
||||
})
|
||||
|
||||
// set up ts support
|
||||
config.module
|
||||
.rule('ts')
|
||||
|
||||
@@ -3,6 +3,7 @@ import { merge } from 'webpack-merge';
|
||||
import Config from 'webpack-chain';
|
||||
import fs from 'fs';
|
||||
|
||||
import { hasDependency } from "../helpers/dependencies";
|
||||
import { getPlatformName } from '../helpers/platform';
|
||||
import { env as _env, IWebpackEnv } from '../index';
|
||||
import { error } from "../helpers/log";
|
||||
@@ -46,18 +47,20 @@ export default function (config: Config, env: IWebpackEnv = _env): Config {
|
||||
});
|
||||
});
|
||||
|
||||
config.plugin('ForkTsCheckerWebpackPlugin').tap((args) => {
|
||||
args[0] = merge(args[0], {
|
||||
typescript: {
|
||||
extensions: {
|
||||
vue: {
|
||||
enabled: true,
|
||||
compiler: 'nativescript-vue-template-compiler',
|
||||
config.when(hasDependency('typescript'), (config) => {
|
||||
config.plugin('ForkTsCheckerWebpackPlugin').tap((args) => {
|
||||
args[0] = merge(args[0], {
|
||||
typescript: {
|
||||
extensions: {
|
||||
vue: {
|
||||
enabled: true,
|
||||
compiler: 'nativescript-vue-template-compiler',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
return args;
|
||||
});
|
||||
return args;
|
||||
});
|
||||
|
||||
// add VueLoaderPlugin as the first plugin
|
||||
|
||||
@@ -0,0 +1,96 @@
|
||||
// @ts-nocheck
|
||||
// This is a runtime module - included by nativescript-hot-loader
|
||||
// todo: log correct message format for CLI to pick up
|
||||
// todo: build CLI service to listen for state changes
|
||||
// ---
|
||||
import { Http } from '@nativescript/core'
|
||||
|
||||
let __NS_DEV_HOST_URL__;
|
||||
Promise.race(__NS_DEV_HOST_IPS__
|
||||
.map(ip => `http://${ip}:8238/`)
|
||||
.map(async url => {
|
||||
await Http.request({
|
||||
method: 'get',
|
||||
url
|
||||
})
|
||||
|
||||
return url;
|
||||
})).then(winner => {
|
||||
__NS_DEV_HOST_URL__ = winner
|
||||
})
|
||||
|
||||
if(module.hot) {
|
||||
module.hot.dispose(() => {
|
||||
console.log('Disposing entry file?!')
|
||||
// require('@nativescript/core').Application.resetRootView()
|
||||
})
|
||||
|
||||
const orig = global.__onLiveSync
|
||||
const log = (type, info) => {
|
||||
console.log(`[nds] HMR ${type}:`, info)
|
||||
// console.log(__NS_DEV_HOST_IPS__[0])
|
||||
|
||||
if(__NS_DEV_HOST_URL__) {
|
||||
Http.request({
|
||||
method: 'post',
|
||||
url: __NS_DEV_HOST_URL__,
|
||||
content: JSON.stringify({
|
||||
type,
|
||||
info
|
||||
})
|
||||
}).catch(err => {
|
||||
console.log(err)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
log('init')
|
||||
|
||||
module.hot.addStatusHandler(status => {
|
||||
log('status', status)
|
||||
})
|
||||
|
||||
global.__onLiveSync = async function () {
|
||||
// handle hot updated on LiveSync
|
||||
console.log('~~~ livesynced ~~~')
|
||||
|
||||
log('checking')
|
||||
await module.hot.check().catch(err => {
|
||||
log('checking-failed', err)
|
||||
});
|
||||
log('checked')
|
||||
log('applying')
|
||||
await module.hot.apply({
|
||||
ignoreUnaccepted: false,
|
||||
ignoreDeclined: false,
|
||||
ignoreErrored: false,
|
||||
|
||||
onDeclined(info) {
|
||||
log('declined', info)
|
||||
},
|
||||
onUnaccepted(info) {
|
||||
log('unaccepted', info)
|
||||
},
|
||||
onAccepted(info) {
|
||||
log('accepted', info)
|
||||
},
|
||||
onDisposed(info) {
|
||||
log('disposed', info)
|
||||
},
|
||||
onErrored(info) {
|
||||
log('errored', info)
|
||||
}
|
||||
}).catch((err) => {
|
||||
log('applying-failed', err)
|
||||
})
|
||||
// log('applying')
|
||||
// await module.hot.apply()
|
||||
log('applying-done')
|
||||
// await module.hot.apply()
|
||||
setTimeout(() => {
|
||||
orig();
|
||||
});
|
||||
};
|
||||
|
||||
// global.__onLiveSync()
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
import { relative } from "path";
|
||||
import { relative, resolve } from "path";
|
||||
import dedent from "ts-dedent";
|
||||
import fs from 'fs';
|
||||
|
||||
// note: this will bail even if module.hot appears in a comment
|
||||
const MODULE_HOT_RE = /module\.hot/
|
||||
@@ -11,6 +12,16 @@ export default function loader(content: string, map: any) {
|
||||
}
|
||||
const opts = this.getOptions();
|
||||
|
||||
// used to inject the HMR runtime into the entry file
|
||||
if(opts.injectHMRRuntime) {
|
||||
const hmrRuntimePath = resolve(__dirname, './hmr.runtime.js')
|
||||
const hmrRuntime = fs.readFileSync(hmrRuntimePath).toString()
|
||||
.split('// ---')[1]
|
||||
.replace('//# sourceMappingURL=hmr.runtime.js.map', '')
|
||||
|
||||
return this.callback(null, `${content}\n${hmrRuntime}`, map)
|
||||
}
|
||||
|
||||
const relativePath = relative(
|
||||
opts.appPath ?? this.rootContext,
|
||||
this.resourcePath
|
||||
|
||||
Reference in New Issue
Block a user