typescript - ts-loader -> file-loader löser inte require-beroenden


Jag vill skapa en service worker.

DISCLAIMER: Jag vill inte använda serviceworker-webpack-plugin, det lägger till mycket överflödig arbetsbörda som jag helt enkelt inte behöver. Jag är 100% säker på att webpack kan leverera transpilerade js/ts-filer som statiska filer.

Så jag har main.ts och sw.ts:

  • main.ts bör transpileras via ts-loader och injiceras i index.html. När jag kör webpack-dev-server bör main.ts stödja autoreload, precis som dev-server gör som standard.
  • sw.ts å andra sidan bör också transpileras via ts-loader och det SKA INTE injiceras i index.html. Dessutom, om jag kör webpack-dev-server, borde dev-servern inte lägga till hotreload JS-kod där. Jag vill bara att sw.js ska transpilieras.
  • Jag skulle också vilja ha en referens till sw.js under körning från main.js. File-loader bör tillhandahålla den på samma sätt som det gör för .css-filer.

Försök #1

Mitt första försök var att skapa 2 poster i webpack-konfigurationen som nedan:

entry: {'main': './src/main.ts', 'sw':'./src/sw.ts'},

För att förhindra att sw.ts injiceras kunde jag använda index.ejs och manuellt kontrollera js-filnamnet för om. Detta scenario fungerar men medan jag är på dev-server, lägger webpack-dev-server till hotreload-kod och sw.js misslyckas vid körning med window not defined, vilket är logiskt, eftersom service workers inte har ett window-objekt.

Försök #2, länk till GitHub

Men sedan provade jag file-loader, som ser ut som nedan:

webpack.config.js:

const HtmlWebpackPlugin=require("html-webpack-plugin");

module.exports = {
  entry: ['./src/main.ts'],
  plugins: [
    new HtmlWebpackPlugin({hash: true, template: 'src/index.html'}),
  ],
  devtool: '#source-map',
  module: {
    rules: [
      {
        test: /sw\.ts$/,
        exclude: /node_modules/,
        loader: 'file-loader',
        options: {
          outputPath: '',
          name: 'sw.js?[sha512:hash:base64:6]',
        }
      },
      {
        test: /\.ts$/,
        loader: 'ts-loader',
      },
    ],
  },
};

tsconfig.json:

{
  "compilerOptions": {
    "lib": ["es2017", "dom"],
    "module": "es2015",
    "moduleResolution": "node",
    "target": "es5",
    "sourceMap": true,
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "allowSyntheticDefaultImports": true
  },
  "exclude": [
    "./node_modules"
  ]
}

main.ts;

import './sw.ts'
console.log('main.ts');

sw.ts:

import {LoggerFactory, LogStrict} from 'lines-logger';
console.log('sw file');
let loggerFactory: LoggerFactory = new LoggerFactory(LogStrict.LOG_WITH_WARNINGS);

Utdata sw.js:

import { LoggerFactory, LogStrict } from 'lines-logger';
console.log('sw file');
var loggerFactory = new LoggerFactory(LogStrict.LOG_WITH_WARNINGS);

Varför löser inte webpack modulberoenden? Finns det ett annat sätt att hantera service worker?

Svar #1

Mitt råd (du kommer inte att gilla det) är att service workers har viss komplexitet involverad. Jag rekommenderar att använda ett projekt som WorkBox för att göra ditt liv enklare:

https://developers.google.com/web/tools/workbox/guides/generate-service-worker/webpack

Jag har bloggat om detta tidigare om det kan vara till hjälp: https://blog.johnnyreilly.com/2017/11/the-typescript-webpack-pwa.html

Ursäkta, jag vet att detta inte är exakt vad du letar efter. (Relaterad fråga på ts-loader: https://github.com/TypeStrong/ts-loader/issues/804 )