问题
I developed a webpart in Sharepoint Framework, when I compile it with gulp build it compiles fine, however when I do gulp serve and I add the webpart to the workbench I get this error:
[SPLoaderError.loadComponentError]:
***Failed to load component "3a000c20-ed9a-44db-a466-db477bfc0132" (BuilderWebPart).
Original error: ***Failed to load entry point from component "3a000c20-ed9a-44db-a466-db477bfc0132" (BuilderWebPart).
Original error: Error loading https://component-id.invalid/3a000c20-ed9a-44db-a466-db477bfc0132_0.0.1
Cannot find module "resx-strings"
***INNERERROR:
***Failed to load entry point from component "3a000c20-ed9a-44db-a466-db477bfc0132" (BuilderWebPart).
Original error: Error loading https://component-id.invalid/3a000c20-ed9a-44db-a466-db477bfc0132_0.0.1
Cannot find module "resx-strings"
***CALLSTACK:
Error
at SPError._generateErrorStackForIE (https://localhost:4321/node_modules/@microsoft/sp-loader/dist/sp-loader-assembly_en-us.js:10202:13)
at SPError (https://localhost:4321/node_modules/@microsoft/sp-loader/dist/sp-loader-assembly_en-us.js:10183:9)
at SPLoaderError (https://localhost:4321/node_modules/@microsoft/sp-loader/dist/sp-loader-assembly_en-us.js:4211:9)
at ErrorBuilder.buildErrorWithVerboseLog (https://localhost:4321/node_modules/@microsoft/sp-loader/dist/sp-loader-assembly_en-us.js:3821:9)
at ErrorBuilder.buildLoadComponentError (https://localhost:4321/node_modules/@microsoft/sp-loader/dist/sp-loader-assembly_en-us.js:3743:9)
at Anonymous function (https://localhost:4321/node_modules/@microsoft/sp-loader/dist/sp-loader-assembly_en-us.js:7952:9)
at tryCatch (https://localhost:4321/node_modules/@microsoft/sp-loader/dist/sp-loader-assembly_en-us.js:998:5)
at invokeCallback (https://localhost:4321/node_modules/@microsoft/sp-loader/dist/sp-loader-assembly_en-us.js:1013:5)
at publish (https://localhost:4321/node_modules/@microsoft/sp-loader/dist/sp-loader-assembly_en-us.js:981:7)
at publishRejection (https://localhost:4321/node_modules/@microsoft/sp-loader/dist/sp-loader-assembly_en-us.js:923:3)
The main code files are below BuilderWebpart.ts
import * as React from "react";
import * as ReactDom from "react-dom";
import { Version } from "@microsoft/sp-core-library";
import {
BaseClientSideWebPart,
IPropertyPaneConfiguration,
PropertyPaneTextField,
PropertyPaneDropdown
} from "@microsoft/sp-webpart-base";
//import * as strings from "BuilderWebPartStrings";
import Builder from "./components/Builder";
import { IBuilderProps } from "./components/IBuilderProps";
import { IBuilderWebPartProps } from "./IBuilderWebPartProps";
export default class BuilderWebPart extends BaseClientSideWebPart<IBuilderWebPartProps> {
public render(): void {
const element: React.ReactElement<IBuilderProps > = React.createElement(
Builder,
{
description: this.properties.description,
selectedMeal: this.properties.selectedMeal
}
);
ReactDom.render(element, this.domElement);
}
protected get dataVersion(): Version {
return Version.parse('1.0');
}
protected getPropertyPaneConfiguration(): IPropertyPaneConfiguration {
return {
pages: [
{
header: {
description: "Header"
},
groups: [
{
groupName: "Group",
groupFields: [
PropertyPaneDropdown("meal", {
label: "Select meal",
options: [
{ key: "Veg", text: "Veg" },
{ key: "Nonveg", text: "Nonveg" }
],
selectedKey: "Nonveg"
})
]
}
]
}
]
};
}
}
BuilderWebPart.manifest.json
{
"$schema": "https://dev.office.com/json-schemas/spfx/client-side-web-part-manifest.schema.json",
"id": "3a000c20-ed9a-44db-a466-db477bfc0132",
"alias": "BuilderWebPart",
"componentType": "WebPart",
// The "*" signifies that the version should be taken from the package.json
"version": "*",
"manifestVersion": 2,
// If true, the component can only be installed on sites where Custom Script is allowed.
// Components that allow authors to embed arbitrary script code should set this to true.
// https://support.office.com/en-us/article/Turn-scripting-capabilities-on-or-off-1f2c515f-5d7e-448a-9fd7-835da935584f
"requiresCustomScript": false,
"preconfiguredEntries": [{
"groupId": "5c03119e-3074-46fd-976b-c60198311f70", // Other
"group": { "default": "Other" },
"title": { "default": "builder" },
"description": { "default": "builder description" },
"officeFabricIconFontName": "Page",
"properties": {
"description": "builder"
}
}]
}
Builder.tsx
import * as React from "react";
import styles from "./Builder.module.scss";
import { IBuilderProps } from "./IBuilderProps";
import { escape } from "@microsoft/sp-lodash-subset";
import MealBuilder from "./MealBuilder";
import Meal from "./Meal";
import { IPropertyPaneConfiguration } from "@microsoft/sp-webpart-base/lib/propertyPane/propertyPane/IPropertyPane";
import {
PropertyPaneDropdown
} from "@microsoft/sp-webpart-base";
import Version from "@microsoft/sp-core-library/lib/Version";
export default class Builder extends React.Component<IBuilderProps, {}> {
private mealBuilder: MealBuilder ;
private items: string;
private meal: Meal;
constructor(props: IBuilderProps, state: any) {
super(props);
this.setMeal(props.selectedMeal);
this.mealBuilder = new MealBuilder();
}
public render(): React.ReactElement<IBuilderProps> {
return (
<div className={styles.builder}>
<div className={styles.container}>
<div className={`ms-Grid-row ms-bgColor-themeDark ms-fontColor-white ${styles.row}`}>
<div className="ms-Grid-col ms-lg10 ms-xl8 ms-xlPush2 ms-lgPush1">
<span className="ms-font-xl ms-fontColor-white">Welcome to Burger Company!</span>
<p className="ms-font-l ms-fontColor-white">You have selected the following.</p>
<span className={styles.label}>{this.meal.showItems()}</span>
</div>
</div>
</div>
</div>
);
}
protected get dataVersion(): Version {
return Version.parse("1.0");
}
private setMeal(selectedMeal: string): void {
if(selectedMeal === "VegMeal") {
this.meal = this.mealBuilder.prepareVegMeal();
}
if(selectedMeal === "NonVegMeal") {
this.meal = this.mealBuilder.prepareNonVegMeal();
}
}
}
回答1:
This same thing happened to me when I was implementing a factory design pattern as well. The issue happens because you are referencing imports in a cyclical manner. For instance, If you have class A and Class B:
Class A.B uses Class B.A in the factory.
I see that you have DAOFactory
as an import in SharepointListDAOFactory
and inside SharepointListDAOFactory
you have DAOFactory
imported. The way you correct it is to move the import SharepointListDAOFactory from "./SharepointListDAOFactory";
in DAOFactory
class to the bottom of the file or refactor the abstract classes into interfaces and use them differently.
Updated Code:
import ICustomerDAO from "./ICustomerDAO";
import DataSources from "./DatasourcesEnum";
abstract class DAOFactory {
public abstract getCustomerDAO(): ICustomerDAO;
public static getDAOFactory(whichFactory: DataSources): DAOFactory {
switch (whichFactory) {
case DataSources.SharepointList:
return new SharepointListDAOFactory();
case DataSources.JsonData:
return new JsonDAOFactory();
default :
return null;
}
}
}
export default DAOFactory;
import SharepointListDAOFactory from "./SharepointListDAOFactory";
import JsonDAOFactory from "./JsonDAOFactory";
回答2:
Try to add sp-module-loader in your config.json like the following:
"@microsoft/sp-module-loader": "node_modules/@microsoft/sp-module-loader/dist/sp-module-loader.js"
The code samples from github for your reference:
SharePoint FrameWork client-side web part samples
来源:https://stackoverflow.com/questions/50143932/sploadererror-loadcomponenterror-failed-to-load-component