Ошибка 'окно не определено' при использовании style-loader с веб-пакетом - PullRequest
0 голосов
/ 28 декабря 2018

Сборка приложения реакции на стороне сервера, и при использовании Webpack у меня возникают проблемы с Style-Loader.

Я использую версию "^ 0.23.1", и при запуске сценария для сборки и сборки естьвыпуск от Style-Loader.

Проблема window is not defined

webpack:///./node_modules/style-loader/lib/addStyles.js?:23
    return window && document && document.all && !window.atob;

Кто-нибудь сталкивался с этой проблемой?После просмотра вопросов Stack и Github для style-loader я не могу найти никакого решения.

Вот мой файл веб-пакета:

const path = require('path');
const webpack = require('webpack');

module.exports = {
  // webpack to use node
  target: 'node',
  entry: './src/index.js',
  output: {
    filename: 'client-build.js',
    path: path.resolve(__dirname, 'build/public'),
    publicPath: '/build/public'
  },
  module: {
    rules: [
      {
        test: /\.js$|\.jsx$/,
        loader: 'babel-loader',
        exclude: '/node_modules/',
        options: {
          presets: [
            '@babel/preset-react'
          ]
        }
      },
      {
        test: /\.(s*)css$/,
        loader: ['style-loader', 'css-loader', 'sass-loader']
      },
      {
        test: /\.jpeg$|\.gif$|\.png$|\.svg$|\.woff$|\.ttf$|\.wav$|\.mp3$|\.jpg$|\.pdf$/,
        loader: 'file-loader',
        query: {
          name: 'assets/img/[name].[ext]'
        },
      },
    ]
  },
  plugins: [
    new webpack.ProvidePlugin({
      "React": "react",
    }),
  ],
}

Если есть еще что-то, что вам нужно увидеть, яможете опубликовать это.

Ответы [ 4 ]

0 голосов
/ 26 апреля 2019

Если я понял правильно, я думаю, что вы пытаетесь использовать style-loader для объединения кода на стороне сервера. Если это так, попробуйте сделать это вместо того, чтобы сделать следующее:

    loader: ['style-loader', 'css-loader', 'sass-loader']

Попробуйте это:

    loader: ['css-loader/locals', 'sass-loader']

Загрузчик стилей не должен использоваться в коде на стороне сервера.Таким образом, мы предоставляем тип null-загрузчика вместо css-loader и удаляем загрузчик стилей.Это должно сработать, я думаю.

0 голосов
/ 12 марта 2019

style-loader пытается внедрить стили в head веб-сайта (window / document), который будет отсутствовать на вашем сервере при рендеринге / исполнении.

Вам нужночтобы удалить этот загрузчик из конфигурации сервера и заменить его чем-то другим (например, ExtractTextPlugin или MiniCSSExtractplugin , в зависимости от версии вашего веб-пакета)

0 голосов
/ 23 апреля 2019

У меня была проблема, когда мне нужно было несколько тем и стилей из библиотеки компонентов, которая, в свою очередь, использовала webpack и style-loader.
Мой проект был чистым сценарием и должен генерировать некоторые файлы и поэтому не имел браузера,Он не будет компилироваться вообще, так как загрузчик стилей (и некоторые другие библиотеки) пытался внедрить стили в тег.
Я закончил издеваться над окном и документом, чтобы импортированный проект мог компилироваться.

ПРИМЕЧАНИЕ , что это сработало в моем случае, когда мне понадобилась лишь небольшая часть моей библиотеки компонентов, если вы используете это в более сложном проекте, вероятно, будут некоторые странные ошибки.Но это может помочь кому-то выяснить аналогичную проблему

Запустите это, прежде чем выполнять фактический импорт
Поскольку именно импорт является причиной проблемы, которую вам необходимо сделать перед взломомимпорт.

import * as Hack from './hack/StyleLoaderHack';
Hack.runHack();
...
import {X} from 'your library'

StyleLoaderHack.js

class HackStyle {
    position;

    constructor() {
        this.position = [];
    }
}

class HackElement {
    className;
    childNodes;
    style;

    constructor(tag) {
        this.className = tag;
        this.attributes = [];
        this.childNodes = [];
        this.style = new HackStyle();
    }

    appendChild = (child) => {
        let append;
        if (!(child instanceof HackElement)) {
            append = new HackElement(child);
        } else {
            append = child;
        }
        this.childNodes.push(append);
        return append;
    };

    insertBefore = (newChild, refChild) => {
        let insert;
        if (!(newChild instanceof HackElement)) {
            insert = new HackElement(newChild);
        } else {
            insert = child;
        }
        this.childNodes.push(insert);
    };

    setAttribute = (qualifiedName, value) => {
        // sketchy but works
        this.attributes.push(qualifiedName);
        this.attributes.push(value);
    };
}

class HackDocument {
    head;

    constructor() {
        this.head = new HackElement("head");
    }

    createElement = (tagName) => {
        const element = new HackElement(tagName);
        return element;
    };

    querySelector = (target) => {
        const node = new HackElement(target);
        return node;
    };

    querySelectorAll = (target) => {
        if (target === "[data-emotion-css]") {
            return [];
        }
        const node = new HackElement(target);
        return [node];
    };

    createTextNode = (data) => {
        return new HackElement(data);
    };
}


/**
 * Adds some function to global which is needed to load style-loader, emotion, create-emotion and react-table-hoc-fixed-columns.
 */
export const runHack = () => {
    global.window = {};

    const hackDocument = new HackDocument();
    global.document = hackDocument;
};
0 голосов
/ 11 марта 2019

Я думаю, что ваша проблема в том, что при запуске js-кода на сервере узла нет объекта window.Что также имеет смысл, поскольку на вашем сервере нет окна, в котором отображается ваш код.Вместо этого вы можете использовать объект global для глобальных ссылок, см. Этот пост здесь: Есть ли в файле node.js эквивалент объекта окна в браузере

...