Using webpack ^v2.2.1, I would like to import a TypeScript module as text, in addition to importing the same module "normally".
I've figured that I probably should use the raw-loader. But it isn't working out.
Some example code:
import DemoComponent from './demo'
import demoCode from 'raw-loader!./demo'
TypeScript is screaming at me that something like
error TS2307: Cannot find module 'raw-loader!./demo'.
I'm using ts-loader.
Here is my webpack.config.js:
const { resolve } = require('path')
const fail = require('webpack-fail-plugin')
const config = {
entry: './docs/index.ts',
output: {
filename: 'bundle.js',
path: resolve(__dirname, 'docs-build')
},
resolve: {
extensions: [ '.ts', '.js' ]
},
devtool: 'inline-source-map',
module: {
rules: [
{
enforce: 'pre',
test: /\.js$/,
loader: 'source-map-loader'
},
{
test: /\.ts$/,
loader: 'ts-loader'
},
{
test: /\.scss$/,
use: [
'style-loader',
{
loader: 'css-loader',
options: {
sourceMap: true
}
},
'sass-loader'
]
}
]
},
plugins: [
fail
]
}
module.exports = config
In case anyone is searching for a solution to this answer. Using import is the best option - it will be typed and allow optimizations from module bundlers like Rollup and Webpack 3+ when outputting import vs require:
You need to create a raw-loader.d.ts and make sure it is included by your tsconfig.jsonfile. Enter the following contents:
declare module '!!raw-loader!*' {
const contents: string
export = contents
}
tsconfig.json:
{
"compilerOptions": {
"types": ["raw-loader.d.ts", "node"]
}
}
It seems that the following is working:
import DemoComponent from './demo'
const demoCode = require('!!raw-loader!./demo')
But I'm not sure how correct this is. I would love to find some documentation about the order and mechanism of loaders.
Also, I would prefer to be consistent, by using import statements, instead. But TypeScript is complaining about it if I do a straight conversion:
import DemoComponent from './demo'
import demoCode from '!!raw-loader!./demo'
The error is a simple
error TS2307: Cannot find module '!!raw-loader!./demo'.
I've written a full explanation about it here: https://yonatankra.com/how-to-solve-ts2307-cannot-find-module-when-using-inline-webpack-loaders-with-typescript/
In summary:
You can import using this syntax: import template from 'raw-loader!./component.template.html';
For this to work for any type of file you'd need to:
raw-loader.d.ts
declare module '!!raw-loader!*' {
const contents: string
export default contents
}
tsConfig.json and add the allowSyntheticDefaultImports property to allow modules without a default export to be imported this way:{
"compilerOptions": {
"types": ["raw-loader.d.ts", "node"],
"allowSyntheticDefaultImports": true
}
In the article I also explain how to make this work if (for some truly bizarre reason) you'd like to use template.default.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With