Convert app-context-init to typescript and fix server.go
Typescript doesn't add .js extension to the imported file name. As a result, the browser imports the same file twice with different names: for example app-context and app-context.js. After the fix, server.go patches the typescript output and adds .js extension. Rollup handles such cases correctly. Change-Id: I3290f9244bb6d6dd8547fbceed8ed57186c6f638
This commit is contained in:
@@ -14,17 +14,24 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
import {appContext} from './app-context.js';
|
import {appContext, AppContext} from './app-context';
|
||||||
import {FlagsServiceImplementation} from './flags/flags_impl.js';
|
import {FlagsServiceImplementation} from './flags/flags_impl';
|
||||||
import {GrReporting} from './gr-reporting/gr-reporting_impl.js';
|
import {GrReporting} from './gr-reporting/gr-reporting_impl';
|
||||||
import {EventEmitter} from './gr-event-interface/gr-event-interface_impl.js';
|
import {EventEmitter} from './gr-event-interface/gr-event-interface_impl';
|
||||||
import {Auth} from './gr-auth/gr-auth_impl.js';
|
import {Auth} from './gr-auth/gr-auth_impl';
|
||||||
|
|
||||||
const initializedServices = new Map();
|
type ServiceName = keyof AppContext;
|
||||||
|
type ServiceCreator<T> = () => T;
|
||||||
|
|
||||||
function getService(serviceName, serviceInit) {
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
|
const initializedServices: Map<ServiceName, any> = new Map();
|
||||||
|
|
||||||
|
function getService<K extends ServiceName>(
|
||||||
|
serviceName: K,
|
||||||
|
serviceCreator: ServiceCreator<AppContext[K]>
|
||||||
|
): AppContext[K] {
|
||||||
if (!initializedServices.has(serviceName)) {
|
if (!initializedServices.has(serviceName)) {
|
||||||
initializedServices.set(serviceName, serviceInit());
|
initializedServices.set(serviceName, serviceCreator());
|
||||||
}
|
}
|
||||||
return initializedServices.get(serviceName);
|
return initializedServices.get(serviceName);
|
||||||
}
|
}
|
||||||
@@ -33,23 +40,30 @@ function getService(serviceName, serviceInit) {
|
|||||||
* The AppContext lazy initializator for all services
|
* The AppContext lazy initializator for all services
|
||||||
*/
|
*/
|
||||||
export function initAppContext() {
|
export function initAppContext() {
|
||||||
const registeredServices = {};
|
function populateAppContext(
|
||||||
function addService(serviceName, serviceCreator) {
|
serviceCreators: {[P in ServiceName]: ServiceCreator<AppContext[P]>}
|
||||||
if (registeredServices[serviceName]) {
|
) {
|
||||||
throw new Error(`Service ${serviceName} already registered.`);
|
const registeredServices = Object.keys(serviceCreators).reduce(
|
||||||
}
|
(registeredServices, key) => {
|
||||||
registeredServices[serviceName] = {
|
const serviceName = key as ServiceName;
|
||||||
configurable: true, // Tests can mock properties
|
const serviceCreator = serviceCreators[serviceName];
|
||||||
get() {
|
registeredServices[serviceName] = {
|
||||||
return getService(serviceName, serviceCreator);
|
configurable: true, // Tests can mock properties
|
||||||
|
get() {
|
||||||
|
return getService(serviceName, serviceCreator);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
return registeredServices;
|
||||||
},
|
},
|
||||||
};
|
{} as PropertyDescriptorMap
|
||||||
|
);
|
||||||
|
Object.defineProperties(appContext, registeredServices);
|
||||||
}
|
}
|
||||||
|
|
||||||
addService('flagsService', () => new FlagsServiceImplementation());
|
populateAppContext({
|
||||||
addService('reportingService',
|
flagsService: () => new FlagsServiceImplementation(),
|
||||||
() => new GrReporting(appContext.flagsService));
|
reportingService: () => new GrReporting(appContext.flagsService),
|
||||||
addService('eventEmitter', () => new EventEmitter());
|
eventEmitter: () => new EventEmitter(),
|
||||||
addService('authService', () => new Auth(appContext.eventEmitter));
|
authService: () => new Auth(appContext.eventEmitter),
|
||||||
Object.defineProperties(appContext, registeredServices);
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -168,17 +168,20 @@ func handleSrcRequest(compiledSrcPath string, dirListingMux *http.ServeMux, writ
|
|||||||
writer.Header().Set("Content-Type", "text/html")
|
writer.Header().Set("Content-Type", "text/html")
|
||||||
} else if isJsFile {
|
} else if isJsFile {
|
||||||
// The following code updates import statements.
|
// The following code updates import statements.
|
||||||
// 1. Keep all imports started with '.' character unchanged (i.e. all relative
|
// 1. if an in imported file has .js or .mjs extension, the code keeps
|
||||||
// imports like import ... from './a.js' or import ... from '../b/c/d.js'
|
// the file extension unchanged. Otherwise, it adds .js extension
|
||||||
// 2. For other imports it adds '/node_modules/' prefix. Additionally,
|
// 2. For module imports it adds '/node_modules/' prefix.
|
||||||
// if an in imported file has .js or .mjs extension, the code keeps
|
|
||||||
// the file extension unchanged. Otherwise, it adds .js extension.
|
|
||||||
// Examples:
|
// Examples:
|
||||||
// '@polymer/polymer.js' -> '/node_modules/@polymer/polymer.js'
|
// '@polymer/polymer.js' -> '/node_modules/@polymer/polymer.js'
|
||||||
// 'page/page.mjs' -> '/node_modules/page.mjs'
|
// 'page/page.mjs' -> '/node_modules/page.mjs'
|
||||||
// '@polymer/iron-icon' -> '/node_modules/@polymer/iron-icon.js'
|
// '@polymer/iron-icon' -> '/node_modules/@polymer/iron-icon.js'
|
||||||
moduleImportRegexp := regexp.MustCompile("(?m)^(import.*)'([^/.].*?)(\\.(m?)js)?';$")
|
// './element/file' -> './element/file.js'
|
||||||
data = moduleImportRegexp.ReplaceAll(data, []byte("$1 '/node_modules/$2.${4}js';"))
|
moduleImportRegexp := regexp.MustCompile("(?m)^(import.*)'(.*?)(\\.(m?)js)?';$")
|
||||||
|
data = moduleImportRegexp.ReplaceAll(data, []byte("$1 '$2.${4}js';"))
|
||||||
|
|
||||||
|
moduleImportRegexp = regexp.MustCompile("(?m)^(import.*)'([^/.].*)';$")
|
||||||
|
data = moduleImportRegexp.ReplaceAll(data, []byte("$1 '/node_modules/$2';"))
|
||||||
|
|
||||||
writer.Header().Set("Content-Type", "application/javascript")
|
writer.Header().Set("Content-Type", "application/javascript")
|
||||||
} else if strings.HasSuffix(normalizedContentPath, ".css") {
|
} else if strings.HasSuffix(normalizedContentPath, ".css") {
|
||||||
writer.Header().Set("Content-Type", "text/css")
|
writer.Header().Set("Content-Type", "text/css")
|
||||||
|
|||||||
Reference in New Issue
Block a user