构建服务器端react应用程序,并且在使用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问题之后,我没有找到任何解决方案。
这是我的webpack文件:
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",
}),
],
}
如果还有其他任何需要,我可以张贴。
答案 0 :(得分:4)
我认为您的问题是,在节点服务器上运行js代码时没有window
对象。这也很有意义,因为您的服务器没有呈现代码的窗口。您可以将global
对象用于全局引用,请参见此处的相关文章:Does node.js have equivalent to window object in browser
答案 1 :(得分:0)
我遇到了一个问题,需要组件库中的一些主题和样式,而组件库又使用了webpack和style-loader。
我的项目是纯脚本,应该生成一些文件,因此没有浏览器。由于style-loader(和其他一些lib)试图将样式注入标签中,因此根本无法编译。
我结束了模拟窗口和文档,以便可以编译导入的项目。
注意,这在我只需要组件库的一小部分的情况下有效,如果在更复杂的项目中使用它,可能会出现一些奇怪的错误。但这可能会帮助某人找出类似的问题
在实际导入之前运行此程序
由于是实际的导入导致了问题,因此您需要在导入之前进行修改。
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;
};
答案 2 :(得分:0)
如果我正确理解,我认为您正在尝试使用样式加载器来捆绑服务器端代码。如果是这种情况,请尝试这样做而不是这样做:
loader: ['style-loader', 'css-loader', 'sass-loader']
尝试一下:
loader: ['css-loader/locals', 'sass-loader']
不应在服务器端代码上使用样式加载器。因此,我们提供了一种null加载程序而不是css-loader,并删除了样式加载程序。我猜这应该可以解决问题。