我试图学习反应,并在现有项目中介绍它。因此,我想在一些有意义的地方使用反应,而不是在任何地方使用它。
问题是我无法理解的切入点概念。我更喜欢:
ReactDOM.render(
<MyComponent/>,
document.getElementById("componentExample")
);
在cshtml
附近<div id='componentExample'></div>
内,而不是在单独的jsx
内。我知道我无法在jsx
中使用cshtml
语法,但如果我写的话
<script src="@Url.Content("~/Scripts/dist/bundle.js")"></script>
<script>
ReactDOM.render(
React.createElement(MyComponent, {}, null), document.getElementById("componentExample")
);
</script>
这不起作用,因为MyComponent
未定义。它包含在我的bundle.js
中(我必须将其添加为入口点),但它属于某些webpack
内容的范围,并且不会公开。
这样做的正确方法是什么?
我的目标是为我的应用程序编写一些更适合的组件,并在这里和那里使用它,而不必完全进入基于反应的架构。
我的设置为webpack
+ babel polyfill
+ typescript
+ react
,此内容位于ASP.NET MVC
。
我的webpack.config.js
是:
var config = {
entry: ['babel-polyfill', "./SiteScripts/React/index.tsx", "./SiteScripts/React/Components/MyComponent.tsx"],
output: {
filename: "./Scripts/dist/bundle.js",
},
// Enable sourcemaps for debugging webpack's output.
devtool: "source-map",
resolve: {
// Add '.ts' and '.tsx' as resolvable extensions.
extensions: [".webpack.js", ".web.js", ".ts", ".tsx", ".js"]
},
module: {
rules: [
// All output '.js' files will have any sourcemaps re-processed by 'source-map-loader'.
{
enforce: 'pre',
test: /\.js$/,
loader: "source-map-loader"
},
// All files with a '.ts' or '.tsx' extension will be handled by 'ts-loader'.
{
test: /\.tsx?$/, loaders: ['babel-loader', "ts-loader"], exclude: /node_modules/
}
]
},
plugins : []
}
if (process.env.NODE_ENV === "production") {
config.devtool = "cheap-module-source-map";
}
module.exports = config;
这也与问题有关(关于架构的问题):我想让我的bundle.js
更小 - 现在是30k线。可能是因为我试图以错误的方式使用react
?
答案 0 :(得分:0)
我终于找到了问题。我有一些错误(并没有完全理解webpack背后的整个理论),答案是我在问题中给出的代码,因此我没有任何答案。
首先我必须捆绑一个库,以便导出其中定义的内容(webpack.config.js
):
entry: ['babel-polyfill', "./SiteScripts/React/index.tsx"],
output: {
filename: "./Scripts/dist/bundle.js",
libraryTarget: "var",
library: "WebPack"
},
这将使index.tsx
中定义的类型/变量(我认为仅从条目列表中获取最后一个文件)和exported
- 可通过WebPack.<name>
我需要导出我的组件。我已经这样做了 - 但可能有更好的方法(index.tsx
):
import { MyComponent} from "./Components/mycomponent";
export var myComponent = MyComponent;
我还需要确保所有子组件都是模块。这意味着在任何地方都使用import
,并为所有元素,道具和州添加关键字export
。
之后我能够从:
渲染我的组件<script src="@Url.Content("~/Scripts/dist/bundle.js")"></script>
<script>
ReactDOM.render(
React.createElement(WebPack.myComponent,
{
PropA = 2, PropB = "3"
}, null),
document.getElementById("componentExample")
);
</script>
如果我这样做,还有一件事需要注意:<script src="@...
行在我的结果html中不会发生多次(这很可能是因为我使用嵌入在单个页面中的许多组件) 。我使用这个javascript函数来确保我只加载bundle.js
一次:
function loadJsOnce(url, whenFinish) {
if (!window.loadedScripts) {
window.loadedScripts = {};
}
if (!window.loadedScripts[url]) {
var script = document.createElement('script');
//script.async = true; // remove this if you don't want the script to be async
script.src = url;
script.onload = function() {
whenFinish();
}
document.getElementsByTagName('head')[0].appendChild(script);
window.loadedScripts[url] = true;
} else {
whenFinish();
}
}
在url
我指定了bundle.js
的路径,在whenFinish
函数中,我放了一个调用ReactDOM.render(...
内容的函数