Search code examples
node.jswebpackwebpack-2typescript2.0raw-loader

How to use Webpack 2 Raw-Loader to read files


I am currently stuck in a spot where I need to start a NodeJS server in HTTPS mode and need to read in the cert files in order to give them as options in the https.createServer(options, app).listen(8443) command. I am having a hard time grasping onto how to read files into a TypeScript file that is bundled using Webpack 2. For example,

I have 2 files file.crt and file.key. I want to read these files in when i create the https server and start listening on a given port. In regular TS/JS land I could do this:

```

import Config from '../env/config';
import Express from '../lib/express';
import * as https from 'https';

import * as fs from 'fs';

let config = new Config();
let app = Express.bootstrap().app;

export default class AppService{

  constructor(){
    // console.log('blah:', fs.readFileSync('./file.txt'));
  }

  start(){

    let options = {
      key: fs.readFileSync('file.key'),
      cert: fs.readFileSync('file.crt'),
      ca: fs.readFileSync('ca.crt'),
      passphrase: 'gulp'
    };

    https.createServer(options, app).listen(config.port,()=>{
      console.log('listening on port::', config.port );
    });

  }
}

However, when webpack 2 builds the bundle these files arent being brought in, so when node starts up it cant find them. Ok, i get it, but I read that raw loader will work for this, so i thought i would give it a try.

Here is my webpack config file:

// `CheckerPlugin` is optional. Use it if you want async error reporting.
// We need this plugin to detect a `--watch` mode. It may be removed later
// after https://github.com/webpack/webpack/issues/3460 will be resolved.
const {CheckerPlugin} = require('awesome-typescript-loader');
const LoaderOptionsPlugin = require('webpack/lib/LoaderOptionsPlugin');

module.exports = {
  target: 'node',
  entry: './src/server.ts',
  output: {
    filename: 'dist/bundle.js'
  },
  resolve: {
    extensions: ['.ts', '.tsx', '.js', '.jsx']
  },
  
  devtool: 'source-map',
  
  module: {
    rules: [
      {test: /\.ts$/, use: 'awesome-typescript-loader'},
      {test: /\.json$/, loader: 'json-loader'},
      {test: /\.crt$/, use: 'raw-loader'}
    
    ]
  },
  plugins: [
    new CheckerPlugin()
  ],
  node: {
    global: true,
    crypto: 'empty',
    fs: 'empty',
    net: 'empty',
    process: true,
    module: false,
    clearImmediate: false,
    setImmediate: false
  }
};

Which, i think, means ok scan project and when you find any files with .crt then bundle them up with the source map as utf8 strings. All I would have to do is this import crtfile from 'file.crt' just like raw-loader doc states, however, typescript cannot even compile the file now stating it cannot file module file.crt. Help please!! Ive hit a wall.


Solution

  • However, when webpack 2 builds the bundle these files arent being brought in, so when node starts up it cant find them.

    Webpack only bundles files you import. In your case you are just reading from the file system, and webpack doesn't touch these functions. That doesn't mean it doesn't work at run time, you simply need to have the files you're trying to read in the directory you're running the bundle in, the functions don't have a different meaning in the bundle.

    If you want to have the content of the files in the bundle, you can indeed use the raw-loader. First the import statement needs to be a relative path, otherwise it looks for a module.

    import crtfile from './file.crt';
    

    With your config that would work fine in JavaScript. In TypeScript the import would be:

    import * as crtfile from './file.crt';
    

    But TypeScript is not happy with importing files whose types are not known. You can work around that by defining the types in a declaration file, for instance custom.d.ts (as shown in Importing non code assets).

    declare module "*.crt" {
      const content: any;
      export default content;
    }