[英]How to isolate components in React app.js bundle
The project index.html
load reactjs & babel to render app.js.项目
index.html
加载 reactjs 和 babel 来渲染 app.js。
<body>
<h1>Placeholder title</h1>
<div id="root"></div>
<script src='js/react.production.min.js'></script>
<script src='js/react-dom.production.min.js'></script>
<script src='js/babel.min.js'></script>
<script type='text/babel' src='js/APP/app.js'></script>
</body>
The project app.js
load the App and the component Note项目
app.js
加载 App 和组件 Note
function App() {
return <Note note='Hello World!' />;
}
function Note({ note }){
return <div>{ `Note: ${note}` }</div>;
}
ReactDOM.render(<App />, document.getElementById('root'));
import Note from './components/Note'
???import Note from './components/Note'
???import Note from './components/Note'
function App() {
return <Note note='Hello World!' />;
}
In this case在这种情况下
const Hello = require('./components/Hello') // option 1 error
import Hello from './components/Note' // option 2 error
function App() {
return <Note note='Hello World!' />;
}
This throw the error Uncaught ReferenceError: require is not defined
这会抛出错误
Uncaught ReferenceError: require is not defined
How this can be done?如何做到这一点?
You need to specify module
, but there are some obstacles to be overcome ...您需要指定
module
,但有一些障碍需要克服......
You can find some information at:您可以在以下位置找到一些信息:
It doesn't work directly from the file system, it only works if the file is provided by a server over HTTP(S).它不能直接从文件系统工作,只有在服务器通过 HTTP(S) 提供文件时才有效。
There are many possible solutions.有许多可能的解决方案。 If you have python installed, an easy to use server would be to go into the folder where the
index.html
is and run:如果您安装了 python,一个易于使用的服务器将进入
index.html
所在的文件夹并运行:
python -m http.server 3000
In modern Browsers , you can use import
, if you specify type="module"
, but that's without JSX:在现代浏览器中,如果指定
type="module"
,则可以使用import
,但没有 JSX:
// index.html
<!DOCTYPE html><html lang="en"><head>
<script type="module">
import { doSomething } from './js/module.js';
doSomething();
</script>
</head></html>
// js/module.js
import { doSomethingElse } from './module2.js';
export const doSomething = function(){
console.log('done something.');
doSomethingElse();
};
// js/module2.js
export const doSomethingElse = function(){
console.log('done something else.');
};
(This also doesn't work "as usual" with eg <button onClick="myFunction()">
, for workarounds see es6-modules-undefined-onclick-function-after-import ) (这也不能“像往常一样”使用例如
<button onClick="myFunction()">
,有关解决方法,请参阅es6-modules-undefined-onclick-function-after-import )
You can use JSX and a module by specifying type="text/babel"
and data-type="module"
, but only one level down (only the files or inline scripts with type="text/babel"
work) :您可以通过指定
type="text/babel"
和data-type="module"
来使用 JSX 和模块,但只能向下一级(只有type="text/babel"
的文件或内联脚本工作) :
// index.html
<!DOCTYPE html><html lang="en"><body>
<h1>Placeholder title</h1>
<div id="root"></div>
<script src='js/react.production.min.js'></script>
<script src='js/react-dom.production.min.js'></script>
<script src='js/babel.min.js'></script>
<script type="text/babel" data-type="module" src='js/app.js'></script>
</body></html>
// js/app.js
import { Note } from './js/note.js';
function App() {
return <Note note='Hello World!' />; // <-- works
}
ReactDOM.render(<App />, document.getElementById('root')); // <-- works
// js/note.js
export function Note({ note }){
return React.createElement( 'div', null, `Note: ${note}`); // <-- works
//return <div>{ `*Note: ${note}` }</div>; // <-- doesn't work
}
You can read more information (and maybe workarounds) in how-to-make-script-type-both-text-babel-and-module .您可以在how-to-make-script-type-both-text-babel-and-module 中阅读更多信息(可能还有解决方法)。 There is a suggestion to use
eval(Babel.transform( ...
, which I would not recommend to use, because you will not be able to re-use the code if eg you migrate to using webpack.有一个建议使用
eval(Babel.transform( ...
,我不建议使用它,因为如果例如您迁移到使用 webpack,您将无法重用代码。
Instead I would recommend to install the babel-cli locally, and convert the js files in a compile step every time before refreshing the browser.相反,我建议在本地安装 babel-cli ,并在每次刷新浏览器之前在编译步骤中转换 js 文件。
yarn add @babel/cli @babel/core @babel/preset-react --dev
type="module"
, and the src
to dist/app.js
type="module"
,将src
改回dist/app.js
--out-dir
and import location accordingly) --out-dir
和导入位置)// index.html
<!DOCTYPE html><html lang="en"><body>
<h1>Placeholder title</h1>
<div id="root"></div>
<script src="js/react.production.min.js"></script>
<script src="js/react-dom.production.min.js"></script>
<script src="js/babel.min.js"></script>
<script type="module" src="dist/app.js"></script>
</body></html>
// app.js
import { Note } from './note.js'; // <-- relative to `/dist` now
function App() {
return <Note note='Hello World!' />; // <-- will work in transpiled /dist folder
}
ReactDOM.render(<App />, document.getElementById('root')); // <-- will work in transpiled /dist folder
// note.js
export function Note({ note }){
// return React.createElement( 'div', null, `Note: ${note}`); // <-- works
return <div>{ `*Note: ${note}` }</div>; // <-- will work in transpiled /dist folder
}
/dist
:/dist
:yarn babel ./js/*.js --presets=@babel/preset-react --out-dir dist
Start the server with eg python -m http.server 3000
and open http://localhost:3000
in the browser.使用例如
python -m http.server 3000
启动服务器并在浏览器中打开http://localhost:3000
。
When you change some code, transpile again, and just refresh the page in the Browser (F5).当您更改某些代码时,再次转换,然后在浏览器中刷新页面 (F5)。
After all, maybe you will endup using webpack or (and) create-react-app , which does all this automatically, leading to a very comfortable development process.毕竟,也许您最终会使用webpack或(和) create-react-app ,它们会自动完成所有这些工作,从而带来非常舒适的开发过程。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.