Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

No sourcemaps when using custom templates #1219

Closed
aendra-rininsland opened this issue May 29, 2019 · 4 comments
Closed

No sourcemaps when using custom templates #1219

aendra-rininsland opened this issue May 29, 2019 · 4 comments
Labels

Comments

@aendra-rininsland
Copy link

aendra-rininsland commented May 29, 2019

Expected behaviour

When using a custom template that throws an exception, html-webpack-plugin should report the relevant file and line number in the stack trace.

Current behaviour

It gives a stack trace like the following:

Screenshot 2019-05-29 at 17 21 58

This is even after adding:

import 'source-map-support/register';

...to my server.js template file.

Environment

Node.js v10.15.3
darwin 18.6.0
6.9.0
html-webpack-plugin-1219@1.0.0 /Users/andrew.rininsland/Projects/html-webpack-plugin-1219
└── webpack@4.32.2

html-webpack-plugin-1219@1.0.0 /Users/andrew.rininsland/Projects/html-webpack-plugin-1219
└── html-webpack-plugin@3.2.0

Config

Copy the minimal webpack.config.js to produce this issue:

import ExtractCssChunksPlugin from 'extract-css-chunks-webpack-plugin';
import HtmlWebpackPlugin from 'html-webpack-plugin';
import { resolve } from 'path';
import dartSass from 'sass';
import getContext from './config';

const buildTime = new Date();

module.exports = async (env = 'development') => {
  const initialState = { ...(await getContext(env)), buildTime };

  return {
    mode: env,
    entry: ['./client/index.js'],
    output: {
      path: resolve(__dirname, 'dist'),
    },
    module: {
      rules: [
        {
          test: /\.js$/,
          exclude: /node_modules/,
          use: {
            loader: 'babel-loader',
            options: {
              presets: [
                '@babel/preset-env',
                '@babel/preset-react',
              ],
            },
          },
        },
      },
    },
    devtool: env === 'development' ? 'inline-source-map' : 'source-map',
    plugins: [
      new ExtractCssChunksPlugin(),
      new HtmlWebpackPlugin({
        template: './server/index.js',
        templateParameters: initialState,
        filename: 'index.html',
      }),
    ]
  };
};

Copy your template file if it is part of this issue:

server/index.js

import 'source-map-support/register';
import 'undom/register';
import React from 'react';
import { renderToString } from 'react-dom/server';
import { HtmlHead } from '@financial-times/g-components';
import criticalPath from '@financial-times/g-components/shared/critical-path.scss';
import App from '../client/app';

export default (context) => {
  const {
    buildTime, id, flags,
  } = context;

  // These get added to the opening <html> element below.
  const htmlAttributes = Object.entries({
    lang: 'en-GB',
    'data-buildtime': buildTime,
  }).map(([k, v]) => `${k}="${v}"`);

  return `
    <!doctype html>
    <html ${htmlAttributes.join(' ')}>
      <!-- Critical path CSS -->
      <link rel="stylesheet" href="${criticalPath}" />
      ${renderToString(<HtmlHead {...context} />)}
      <body>
        <div id="app">${renderToString(<App {...context} />)}</div>
      </body>
    </html>
  `.trim();
};

client/index.js

import React from 'react';
import { hydrate } from 'react-dom';
import App from './app';
import './styles.scss';

(async () => {
  try {
    window.context = {
      ...(await (await fetch('./context.json')).json()),
      buildTime: window.BUILD_TIME,
    };
    hydrate(<App {...window.context} />, document.getElementById('app'));
  } catch (e) {
    console.error(e);
  }
})();

client/app.js

import React from 'react';

export default (props) => {
  /** 
   *   The following line will cause html-webpack-plugin to throw because
   *   `window.document` isn't available. Unfortunately, it will get reported
   *   as server/index.js ln: 123456 or something, instead of client/app.js
   */
  console.dir(document.querySelectorAll('div'));
  return (<div>yay</div>);
};

Relevant Links

Additional context

My team uses html-webpack-plugin to generate static HTML pages using React, which then get re-hydrated client-side. Admittedly this isn't too well-defined a use case for HTMLWP but it's one that's particularly interesting within the context of the data visualisation/newsmedia communities.

aendra-rininsland pushed a commit to aendra-rininsland/html-webpack-plugin-1219 that referenced this issue May 29, 2019
@jantimon
Copy link
Owner

Did you find any solution for this?

I don't know what can be improved here.
Basically the html-webpack-plugin is using an eval here: (protected using a vm)

const template = this.options.template.replace(/^.+!/, '').replace(/\?.+$/, '');
const vmContext = vm.createContext(_.extend({ HTML_WEBPACK_PLUGIN: true, require: require }, global));
const vmScript = new vm.Script(source, { filename: template });
// Evaluate code and cast to string
let newSource;
try {
newSource = vmScript.runInContext(vmContext);
} catch (e) {
return Promise.reject(e);
}
if (typeof newSource === 'object' && newSource.__esModule && newSource.default) {
newSource = newSource.default;
}
return typeof newSource === 'string' || typeof newSource === 'function'
? Promise.resolve(newSource)
: Promise.reject(new Error('The loader "' + this.options.template + '" didn\'t return html.'));

Any ideas?

@aendra-rininsland
Copy link
Author

Hmm, seems like it's not really possible as per: nodejs/node#8042

Will have a think...

@jantimon
Copy link
Owner

jantimon commented Jul 18, 2019

You could try the following:

Create an entry.js next to your server/index.js which has the following code:

__non_webpack_require__('source-map-support/register');
module.exports = __non_webpack_require__('./server.js');

And point the html_webpack_plugin to use it:

new HtmlWebpackPlugin({
        template: './server/entry.js',

This might even speed up your compilation

@stale
Copy link

stale bot commented Jan 14, 2020

This issue had no activity for at least half a year. It's subject to automatic issue closing if there is no activity in the next 15 days.

@stale stale bot added the wontfix label Jan 14, 2020
@stale stale bot closed this as completed Jan 31, 2020
@lock lock bot locked as resolved and limited conversation to collaborators Mar 10, 2020
# for free to subscribe to this conversation on GitHub. Already have an account? #.
Labels
Projects
None yet
Development

No branches or pull requests

2 participants