如何在没有服务器的情况下运行React应用

时间:2019-03-04 12:34:53

标签: javascript reactjs

我使用 npx create-react-app my-app https://github.com/facebook/create-react-app创建了项目。

运行 npm run build 时,我得到以下信息:

  

70.28 KB build \ static \ js \ 2.93539f7c.chunk.js     22.82 KB构建\静态\ css \ main.cfe0ffe9.chunk.css     1.41 KB(+44 B)build \ static \ js \ main.79f4d9a1.chunk.js 761 B build \ static \ js \ runtime〜main.fdfcfda2.js

     

项目是在假定它托管在服务器根目录下构建的。您   可以使用package.json中的homepage字段来控制它。对于   例如,添加它以为GitHub Pages构建它:

好像我需要服务器才能运行该应用程序。

是否可以在不运行任何服务器的情况下在本地运行此程序?我的意思是因为这只是html,css,js,为什么这里需要服务器?出于什么目的?

构建文件夹中还生成了许多文件,还有index.html和静态文件夹,因此它不像单个bundle.js和单个index.html,看起来更加复杂。

任何人都可以解释为什么build文件夹有这么多文件?以及要考虑使用哪一个来运行该应用?

谢谢

2 个答案:

答案 0 :(得分:2)

  

是否可以在不运行任何服务器的情况下在本地运行此程序?

  

我的意思是因为这只是html,css,js,为什么这里需要服务器?出于什么目的?

React使用XHR加载内容,而XHR无法请求文件方案URL。

  

任何人都可以解释为什么build文件夹有这么多文件吗?

React利用代码分块来优化加载哪些数据。这意味着不会立即使用的JS可以稍后加载,并且不会影响初始页面加载和首次呈现之间的时间。

答案 1 :(得分:0)

默认情况下,假设您的应用程序托管在服务器根目录下,Create React App 会生成一个构建版本。 要覆盖它,请在 package.json 中指定主页,例如:

<body id="body" style="overflow: hidden"> <h1 id="info">loading scene, this might take a few seconds..</h1> <!-- Warning: xhr progress seems to not work over cnd.jsdelivr --> <!-- <div id="loading" id="myProgress"><div id="myBar"></div></div> --> <input class="tool" id="backgroundColor" type="color" value="#2e2e2e"> <script type="x-shader/x-vertex" id="vertexshader"> varying vec2 vUv; void main() { vUv = uv; gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 ); } </script> <script type="x-shader/x-fragment" id="fragmentshader"> uniform sampler2D baseTexture; uniform sampler2D bloomTexture; varying vec2 vUv; void main() { gl_FragColor = ( texture2D( baseTexture, vUv ) + vec4( 1.0 ) * texture2D( bloomTexture, vUv ) ); } </script> <script type="module"> import * as THREE from 'https://threejs.org/build/three.module.js' import Stats from 'https://threejs.org/examples/jsm/libs/stats.module.js' import { GUI } from 'https://threejs.org/examples/jsm/libs/dat.gui.module.js' import { OrbitControls } from 'https://threejs.org/examples/jsm/controls/OrbitControls.js' import { GLTFLoader } from 'https://threejs.org/examples/jsm/loaders/GLTFLoader.js' import { RGBELoader } from 'https://threejs.org/examples/jsm/loaders/RGBELoader.js' import { EffectComposer } from 'https://threejs.org/examples/jsm/postprocessing/EffectComposer.js'; import { ShaderPass } from 'https://threejs.org/examples/jsm/postprocessing/ShaderPass.js'; import { RenderPass } from 'https://threejs.org/examples/jsm/postprocessing/RenderPass.js'; import { UnrealBloomPass } from 'https://threejs.org/examples/jsm/postprocessing/UnrealBloomPass.js'; function $(e){return document.getElementById(e)} function createContainer() { var ctn = document.createElement( 'div' ) document.body.appendChild( ctn ) return ctn } function createScene() { var scn = new THREE.Scene() scn.fog = new THREE.Fog( new THREE.Color("rgb(100, 100, 100)"), 40, 150 ) return scn } function createCamera() { var cam = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 0.1, 1000 ) cam.position.set( 20, 12, 20 ) return cam } function createRenderer() { var rnd = new THREE.WebGLRenderer( { antialias: true } ) rnd.setPixelRatio( window.devicePixelRatio ) rnd.setSize( window.innerWidth, window.innerHeight ) rnd.toneMapping = THREE.ReinhardToneMapping rnd.outputEncoding = THREE.sRGBEncoding rnd.shadowMap.enabled = true rnd.shadowMap.type = THREE.PCFSoftShadowMap container.appendChild( rnd.domElement ) return rnd } function createControls() { var ctr = new OrbitControls( camera, renderer.domElement ) ctr.minDistance = 1 ctr.maxDistance = 50 ctr.enablePan = true ctr.enableZoom = true ctr.enableDamping = true ctr.dampingFactor = 0.1 ctr.rotateSpeed = 0.5 return ctr } function createDirectionalLight() { var drt = new THREE.DirectionalLight( new THREE.Color("rgb(255, 255, 255)"), 1 ) drt.castShadow = true drt.shadow.camera.top = 64 drt.shadow.camera.top = 64 drt.shadow.camera.bottom = - 64 drt.shadow.camera.left = - 64 drt.shadow.camera.right = 64 drt.shadow.camera.near = 0.2 drt.shadow.camera.far = 80 drt.shadow.camera.far = 80 drt.shadow.bias = - 0.002 drt.position.set( 0, 20, 20 ) drt.shadow.mapSize.width = 1024*8 drt.shadow.mapSize.height = 1024*8 // scene.add( new THREE.CameraHelper( drt.shadow.camera ) ) scene.add( drt ) return drt } function createSceneBounds() { var cube = new THREE.Mesh( new THREE.BoxGeometry( 20, 20, 20 ) ) cube.position.y = 0 cube.visible = false scene.add(cube) return new THREE.Box3().setFromObject( cube ); } function createBloomPass() { var blp = new UnrealBloomPass( new THREE.Vector2( window.innerWidth, window.innerHeight ), 1.5, 0.4, 0.85 ) blp.threshold = params.bloomThreshold blp.strength = params.bloomStrength blp.radius = params.bloomRadius return blp } function createFinalPass() { var shp = new ShaderPass( new THREE.ShaderMaterial( { uniforms: { baseTexture: { value: null }, bloomTexture: { value: bloomComposer.renderTarget2.texture } }, vertexShader: document.getElementById( 'vertexshader' ).textContent, fragmentShader: document.getElementById( 'fragmentshader' ).textContent, defines: {} } ), "baseTexture" ); shp.needsSwap = true return shp } function createEnvironment( hdr, onLoad ) { new RGBELoader().setDataType( THREE.UnsignedByteType ).load( hdr, function ( texture ) { const pmremGenerator = new THREE.PMREMGenerator( renderer ) pmremGenerator.compileEquirectangularShader() const envMap = pmremGenerator.fromEquirectangular( texture ).texture scene.environment = envMap texture.dispose() pmremGenerator.dispose() onLoad() } ); } function loadGLTF( file, onLoad ) { new GLTFLoader().load( file , onLoad, function( xhr ) { // Warning: xhr progress seems to not work over cnd.jsdelivr // if ( xhr.lengthComputable ) { // var percentComplete = xhr.loaded / xhr.total * 100 // var elem = document.getElementById("myBar"); // elem.style.width = Math.round(percentComplete, 2) + "%"; // console.log( "Loading Model - " + Math.round(percentComplete, 2) + "%" ) // } }) } const params = { exposure: 1, bloomStrength: 5, bloomThreshold: 0, bloomRadius: 0, scene: "Scene with Glow" }; const container = createContainer() const scene = createScene() const camera = createCamera() const renderer = createRenderer() const controls = createControls() const directionalLight = createDirectionalLight() const sceneBounds = createSceneBounds() const renderScene = new RenderPass( scene, camera ) const bloomPass = createBloomPass() const bloomComposer = new EffectComposer( renderer ) bloomComposer.addPass( renderScene ) bloomComposer.addPass( bloomPass ) const finalPass = createFinalPass() const finalComposer = new EffectComposer( renderer ) finalComposer.addPass( renderScene ) finalComposer.addPass( finalPass ) var model = null var importedMaterial = null var emissiveMaterial = null var mesh = null var meshBounds = null createEnvironment( "https://cdn.jsdelivr.net/gh/miger/bloom-solution/forest.hdr", function() { loadGLTF( "https://cdn.jsdelivr.net/gh/miger/bloom-solution/turntable_121.glb", function ( gltf ) { model = gltf.scene model.traverse( function ( child ) { if ( child.isMesh ) { mesh = child // enable shadows mesh.castShadow = true mesh.receiveShadow = true // set original material importedMaterial = mesh.material importedMaterial.envMapIntensity = 1 // assign temporary black material mesh.material = new THREE.MeshBasicMaterial({color: 0x000000}) // assign bloom only material new THREE.TextureLoader() .load("https://cdn.jsdelivr.net/gh/miger/bloom-solution/RecordPlayer_Emission.jpeg", function( texture ) { texture.flipY = false texture.encoding = THREE.sRGBEncoding emissiveMaterial = new THREE.MeshBasicMaterial({map: texture}); mesh.material = emissiveMaterial }) } }); fitObjectToSceneBounds() scene.add( model ) $("info").style.display = "none" // Warning: xhr progress seems to not work over cnd.jsdelivr // $("loading").style.display = "none" animate() }) }) const animate = function () { requestAnimationFrame( animate ) // set background color scene.background = new THREE.Color( new THREE.Color( $("backgroundColor").value ) ) $('body').attributes['style'].textContent='background-color:'+ $("backgroundColor").value controls.update() bloomComposer.render() // finalComposer.render() }; window.addEventListener( 'resize', function () { const width = window.innerWidth const height = window.innerHeight renderer.setSize( width, height ) bloomComposer.setSize( width, height ); finalComposer.setSize( width, height ); camera.aspect = width / height camera.updateProjectionMatrix() }) function fitObjectToSceneBounds() { meshBounds = new THREE.Box3().setFromObject( model ) let lengthSceneBounds = { x: Math.abs(sceneBounds.max.x - sceneBounds.min.x), y: Math.abs(sceneBounds.max.y - sceneBounds.min.y), z: Math.abs(sceneBounds.max.z - sceneBounds.min.z), }; let lengthMeshBounds = { x: Math.abs(meshBounds.max.x - meshBounds.min.x), y: Math.abs(meshBounds.max.y - meshBounds.min.y), z: Math.abs(meshBounds.max.z - meshBounds.min.z), }; let lengthRatios = [ (lengthSceneBounds.x / lengthMeshBounds.x), (lengthSceneBounds.y / lengthMeshBounds.y), (lengthSceneBounds.z / lengthMeshBounds.z), ]; let minRatio = Math.min(...lengthRatios) let padding = 0 minRatio -= padding model.scale.set(minRatio, minRatio, minRatio) } const gui = new GUI(); gui.add( params, 'exposure', 0.1, 2 ).onChange( function ( value ) { renderer.toneMappingExposure = Math.pow( value, 4.0 ); } ); gui.add( params, 'bloomThreshold', 0.0, 1.0 ).step( 0.001 ).onChange( function ( value ) { bloomPass.threshold = Number( value ); } ); gui.add( params, 'bloomStrength', 0.0, 20.0 ).step( 0.01 ).onChange( function ( value ) { bloomPass.strength = Number( value ); } ); gui.add( params, 'bloomRadius', 0.0, 5.0 ).step( 0.01 ).onChange( function ( value ) { bloomPass.radius = Number( value ); } ); </script> </body>

这将使 Create React App 正确推断要在生成的 HTML 文件中使用的根路径。

来源:https://create-react-app.dev/docs/deployment/#building-for-relative-paths

所以你应该把你的主页指定为当前路径:

"homepage": "http://mywebsite.com/relativepath"