Ts-loader/webpack - how to resolve files outside of working folder with webpack
Asked Answered
M

0

9

I have a project which happens to be a vs code extension, but I think that's not too relevant.

I have the following structure:

./package.json
./tsconfig.json --> references [ ./client, ./server, ./interfaces]

./client
   package.json
   tsconfig.json
   webpack.config.js
./server
   package.json
   tsconfig.json
   webpack.config.js
./interfaces
   package.json
   tsconfig.json

both client and server import from the interfaces project, which just contains some types, interfaces, enums, namespaces, etc that are shared by both. For what it's worth, I don't care if webpack duplicates this into both client.js and server.js bundles, but I do not want to copy/paste the code between the two.

When I run my webpack, I get errors like below wherever I reference the types from interfaces. I should note that building normally through tsc -b works perfectly.

TS2769: No overload matches this call. Overload 1 of 3, '(type: RequestType0<{}, unknown, unknown>, handler: RequestHandler0<{}, unknown>): void', gave the following error. Argument of type 'RequestType' is not assignable to parameter of type 'RequestType0<{}, unknown, unknown>'. Types of property '_' are incompatible. Type '[MyType, MyOtherType, void, void, _EM] | undefined' is not assignable to type '[{}, unknown, unknown, _EM] | undefined'. Type '[MyType, MyOtherType, void, void, _EM]' is not assignable to type '[{}, unknown, unknown, _EM]'. Types of property '3' are incompatible. Type 'void' is not assignable to type '_EM'. Overload 2 of 3, '(type: RequestType, handler: RequestHandler): void', gave the following error. Argument of type 'RequestType' is not assignable to parameter of type 'RequestType'. Types have separate declarations of a private property '_method'. Overload 3 of 3, '(method: string, handler: GenericRequestHandler<{}, unknown>): void', gave the following error. Argument of type 'RequestType' is not assignable to parameter of type 'string'.

It seems like it can't properly process the stuff inside interfaces.

My webpack configs look like this (they are roughly the same, except for filenames):

// ./shared.webpack.config.js
const path = require('path');
const merge = require('merge-options');

module.exports = function withDefaults(/**@type WebpackConfig*/extConfig) {

    /** @type WebpackConfig */
    let defaultConfig = {
        mode: 'none', // this leaves the source code as close as possible to the original (when packaging we set this to 'production')
        target: 'node', // extensions run in a node context
        node: {
            __dirname: false // leave the __dirname-behaviour intact
        },
        resolve: {
            mainFields: ['module', 'main'],
            extensions: ['.ts', '.js'] // support ts-files and js-files
        },
        module: {
            rules: [{
                test: /\.ts$/,
                exclude: /node_modules/,
                use: [{
                    // configure TypeScript loader:
                    // * enable sources maps for end-to-end source maps
                    loader: 'ts-loader',
                    options: {
                        compilerOptions: {
                            "sourceMap": true,
                        }
                    }
                }]
            }]
        },
        externals: {
            'vscode': 'commonjs vscode', // ignored because it doesn't exist
        },
        output: {
            // all output goes into `dist`.
            // packaging depends on that and this must always be like it
            filename: '[name].js',
            path: path.join(extConfig.context, 'out'),
            libraryTarget: "commonjs",
        },
        // yes, really source maps
        devtool: 'source-map'
    };

    return merge(defaultConfig, extConfig);
};

I borrowed these webpack configurations from a similar VS Code extension, although the original extension did not use an `interfaces` project, they just duplicated all the code.

I'm a webpack newbie; how should I modify these configurations to process the interfaces?
// ./client/webpack.config.js
const withDefaults = require('../shared.webpack.config');
const path = require('path');

module.exports = withDefaults({
  context: path.join(__dirname),
  entry: {
    extension: './src/extension.ts',
  },
  output: {
    filename: 'extension.js',
    path: path.join(__dirname, 'out')
  }
});

edit: if I explicitly add an include block to the shared webpack config for all 3 folders, I get a different error, saying that types are not assignable, because the types reference another third-party package, so technically there are two instances of that package:

Types have separate declarations of a private property '_method'.

Marylouisemaryly answered 14/2, 2020 at 20:58 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.