Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

"ReferenceError: document is not defined" when using require() from html file #461

Closed
flipcc opened this issue Mar 3, 2020 · 10 comments
Closed

Comments

@flipcc
Copy link

flipcc commented Mar 3, 2020

**Edit: Changed config to browser target in response to this comment. Problem persists.

  • Operating System: Windows10
  • Node Version: v12.14.0
  • NPM Version: 6.13.4
  • webpack Version: 4.41.5
  • style-loader Version: 1.1.3

Expected Behavior

Require the css file from index.html and have webpack -> file-loader -> style-loader inject it into a link tag in the head (see webpack.config.js). Same as when I import the file from index.js.

<!DOCTYPE html>
<html>
  <head>
-    ${require('../style/main.css')}
+    <link rel="stylesheet" href="main.css">
  </head>
  <body></body>
</html>

Actual Behavior

An error is thrown stating that no link tag can be added as document is not defined.

ERROR in   Error: C:\Users\pmueller\Desktop\project/node_modules/style-loader/dist/runtime/injectStylesIntoLinkTag.js?:39
    var link = document.createElement('link');
               ^
  ReferenceError: document is not defined

Code

// webpack.config.js
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
  mode: 'development',
  entry: './src/scripts/index.js',
  output: {
    filename: 'bundle.js',
    path: path.resolve(__dirname, 'dist')
  },
  devServer: { contentBase: './dist' },
  module: {
    rules: [
      {
        test: /\.html$/i,
        use: [
          {
            loader: 'html-loader',
            options: { interpolate: true }
          }
        ]
      },
      {
        test: /\.css$/i,
        use: [
          {
            loader: 'style-loader',
            options: { injectType: 'linkTag' }
          },
          { loader: 'file-loader' }
        ]
      }
    ]
  },
  plugins: [new HtmlWebpackPlugin({ template: './src/index.html' })]
};
// index.js

/* is empty */
<!-- index.html -->
<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    ${require('../style/main.css')}
    <title>Hello...</title>
  </head>
  <body>
    <div class="some-main-css-class"> ..world.</div>
  </body>
</html>

How Do We Reproduce?

The stated files include everything needed to reproduce the issue raised.

@alexander-akait
Copy link
Member

alexander-akait commented Mar 3, 2020

Do not use style-loader and file-loader together, use style-loader for browsers target and file-loader for node target

@flipcc
Copy link
Author

flipcc commented Mar 3, 2020

@evilebottnawi Combination of css-loader and style-loader does also not work. But you are still right in your remark concerning the build target. I updated my issue description and linked to your comment.

@alexander-akait
Copy link
Member

alexander-akait commented Mar 3, 2020

The error document is not defined says that your environment is not a browser where document is unavailable. Why you include ${require('../style/main.css')} in html? HtmlWebpackPlugin generated script and link tags by itself, you don't need it

Maybe this is an issue that is connected with html-loader like it is stated in this SO answer or this connected issue.

Your problem is not same

@flipcc
Copy link
Author

flipcc commented Mar 3, 2020

@evilebottnawi Ok, i understand your question. So till now we had a line like import './style/main.css in our every index.js/js entry script. But the line felt never right in this place. So I got the task of moving the import from the index.js/entry script into the head of the index.html file. I constructed the above example case, where index.js/the entry script is clear, but now the error about document being undefined arose. But moving the import from the index.js to the index.html does not change the built environment for my understanding.
I am really willing to understand it, as I really want to implement a solution.

@alexander-akait
Copy link
Member

alexander-akait commented Mar 3, 2020

I am really willing to understand it, as I really want to implement a solution.

Can you clarify what do you want? If you need extract styles, please use https://github.com/webpack-contrib/mini-css-extract-plugin.

The template option for the HtmlWebpackPlugin plugin requires interpolate variables on node side, but you use style-loader and it is include browser code for the node environment (${require('../style/main.css')} transforms into the browser code), so you got the error.

@flipcc
Copy link
Author

flipcc commented Mar 3, 2020

Ah ok. Yeah of course require-->node! Thank you so much. Really had a blind spot there.
Have a nice day.

@flipcc flipcc closed this as completed Mar 3, 2020
@biko-san
Copy link

biko-san commented May 8, 2020

@flipcc could you please explain this comment "require-->node!" I am having a similar issue with my webpack implementation.

@flipcc
Copy link
Author

flipcc commented May 9, 2020

With 'blind spot' or 'require--->node' I am referring to the fact, that I wrote import ... , as my mind was still in the web browser. But now with webpack I was working on the server-side/in Node.js. And this means I did have to use require ....

Of course there is a new version of Node.js that supports import/ES Modules, but it is not a LTS version.

Hope this helps.

@AnshulNautiyal
Copy link

For me, the error was that I am using "style-loader" in webpack.server.config.js. which is wrong.
"style-loader" should be used in webpack.client.config.js

@mwood23
Copy link

mwood23 commented Jul 27, 2022

I got this error when using this beside https://www.npmjs.com/package/mini-css-extract-plugin

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants