1

I'm setting up a new project using Svelte, Webpack, and TypeScript. It's based on this template, and running the scripts/setupTypeScript.js script after initial setup to switch to TypeScript.

When trying to import resources that are not TypeScript files, VSCode and TypeScript are showing errors about them:

import myContent from './some-file.txt';
// -> Cannot find module './some-file.txt' or its corresponding type declarations.ts(2307)

Technically this is working, but the errors are noisy and seem to be preventing live-reload. Is there some way to make TypeScript just ignore these imports and trust that Webpack will handle them? Some of these are binary files, so I can't just copy/paste them into .ts files either.

Webpack and TS configs are provided below:

webpack.config.js:

const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const path = require('path');
const sveltePreprocess = require('svelte-preprocess');

const mode = process.env.NODE_ENV || 'development';
const prod = mode === 'production';

module.exports = {
    entry: {
        'build/bundle': ['./src/main.ts']
    },
    resolve: {
        alias: {
            svelte: path.dirname(require.resolve('svelte/package.json'))
        },
        extensions: ['.mjs', '.js', '.ts', '.svelte'],
        mainFields: ['svelte', 'browser', 'module', 'main']
    },
    output: {
        path: path.join(__dirname, '/public'),
        filename: '[name].js',
        chunkFilename: '[name].[id].js'
    },
    module: {
            rules: [
                {
                    test: /\.ts$/,
                    loader: 'ts-loader',
                    exclude: /node_modules/
                },
                {
                    test: /\.svelte$/,
                    use: {
                        loader: 'svelte-loader',
                        options: {
                            compilerOptions: {
                                dev: !prod
                            },
                            emitCss: prod,
                            hotReload: !prod,
                            preprocess: sveltePreprocess({ sourceMap: !prod })
                        }
                    }
                },
                {
                    test: /\.css$/,
                    use: [
                        MiniCssExtractPlugin.loader,
                        'css-loader'
                    ]
                },
                {
                    test: /\.(txt)$/,
                    use: ['raw-loader']
                },
                {
                    test: /\.(ttf|wasm)$/,
                    use: ['file-loader']
                },
                {
                    // required to prevent errors from Svelte on Webpack 5+
                    test: /node_modules\/svelte\/.*\.mjs$/,
                    resolve: {
                        fullySpecified: false
                    }
                }
        ]
    },
    mode,
    plugins: [
        new MiniCssExtractPlugin({
            filename: '[name].css'
        })
    ],
    devtool: prod ? false : 'source-map',
    devServer: {
        hot: true
    }
};

tsconfig.json:

{
        "extends": "@tsconfig/svelte/tsconfig.json",
        "include": ["src/**/*.ts", "src/node_modules/**/*.ts"],
        "exclude": ["node_modules/*", "__sapper__/*", "static/*"]
}
Don McCurdy
  • 10,975
  • 2
  • 37
  • 75
  • Does this answer your question? [Import html from typescript with webpack](https://stackoverflow.com/questions/46503615/import-html-from-typescript-with-webpack) – Etheryte Apr 06 '21 at 19:44
  • Is `use: ['raw-loader']` valid webpack config syntax? Just asking as I can't see a matching example at https://webpack.js.org/concepts/loaders/ but perhaps it's supported but not promoted. – cefn Apr 06 '21 at 21:24
  • I wasn't able to solve this with answers given in the other question, although it does look similar. Adding `// @ts-ignore` comments to each line does seem to avoid the problem, although I'm hoping there's another way. The `['raw-loader']` syntax is allowed, yes, there can be multiple loaders for a type. – Don McCurdy Apr 06 '21 at 22:16

1 Answers1

3

Add a global.d.ts file with the following contents and make sure it's picked up by your include:

declare module "*.txt";

This tells TS "any import ending with .txt is okay, treat it as any". Alternatively, export a default with another type:

declare module "*.txt" {
    const content: string;
    export default content;
}
Don McCurdy
  • 10,975
  • 2
  • 37
  • 75
dummdidumm
  • 4,828
  • 15
  • 26
  • Thank you! This was it. An important detail I didn't find in https://stackoverflow.com/questions/46503615/import-html-from-typescript-with-webpack was that the `global.d.ts` should be part of the `include` entry, not `types` or `typeRoots`. – Don McCurdy Apr 07 '21 at 22:51