I'd like to deploy a React app built with create-react-app within my company's CMS. I can't host assets on the CMS, just the script tag, css tag and root DIV. I've deployed the static assets to S3 and pointed my publicPath to AWS, but in my CSS the components are not rendered. I'm new to webpack configuration and unsure where to turn.
There are only two ways where to build assets for deploy:
build assets on local machine and deploy static files
deploy sources to server and perform assets building there
There are some differences. For example first way may require more data to transfer, and second way requires more complicated configuration on server. Server must have possibility to execute different tools including webpack and have enough place for node modules.
Related
I am building project which I want to deploy on my own static ip server (apache2). I am using postgresql database and python api (want to use it just as API not frontend), currently I am making frontend where I need to use node packages because I need to download and install OpenLayers for usage with OSM maps, when I build nodejs project I get dist/ directory which I need to put to production. I would like to know if it means that I can just put it to /var/www/html directory and if no please where should put it? Or please some explanation how it works :) Thank you very much.
Putting the /dist directory in the /var/www/html directory is fine if it's a static build of the project, but it's recommended that you setup a virtual host so you can configure different sites served by a single Apache instance (e.g. you can run different projects on different sub-domains).
See this guide on setting up a virtual host on Ubuntu.
From the Vue CLI https://cli.vuejs.org/guide/deployment.html, it stated that the dist directory is meant to be served by an HTTP server. But why can't I preview it from the index.html? Cause my understanding is that Vue is just a front end JavaScript framework, so one should be able to preview it from any browser. If am to create a simple vue project using a cdn, it can be directly previewed on the browser. But this is not the case for the vue project created through the CLI. Can someone explain this.
Take a look into the Chrome Dev Tools. You will see a couple of errors similar to those:
As you can see, there are a bunch of files that fail to be imported. This is because these files are not imported using a relative file path, but an absolute one (starting from root, as visible by the prepended / in all files in the index.html).
If you run a local server from the dist directory root will resolve to this directory, allowing the files to be imported properly and your site to be visible in the browser.
However if you simply open the index.html file in your browser, / will resolve to the root of your operating system, which does not contain the files. If you were to copy all those files into the root of your OS, so that the paths would resolve successfully, you would not need a server to view your Vue application.
CLI projects are built with the use on a server in mind. The idea is to just be able to deploy the files in the dist directory to a server and have a working Vue application.
Just to add to a great answer from #aside.
You can use a publicPath configuration option of Vue CLI and set it to '' or ./ - this should be enough to make it work from file system
The value can also be set to an empty string ('') or a relative path (./) so that all assets are linked using relative paths. This allows the built bundle to be deployed under any public path, or used in a file system based environment like a Cordova hybrid app.
vue.config.js
module.exports = {
publicPath: ''
}
I know what these files contain like build contains the minified file which is minified from src file. I need to know how browser works with it. I haven't uploaded my build file to hosting service yet my website got rendered. In the website, <script> SRC was linked to build but there was no build uploaded but a build was created automatically. this behaviour was observed in svelte. But I hope all framework does the same.
As far as I know, build tools like webpack, parcel, ...etc., use BUILD or DIST (Of course you can change it however you want) folder to store production ready build files of the project.
Files in PUBLIC are just copy & pasted to the build/dist folder when build process is finished. You can store index html, images, fonts, favicon or other static text files in there. They are not processed by build tools.
SRC folder is just for storing the whole project's unminified source code.
Most frameworks use 'build/dist - src - public' structure while frameworks like next.js uses root for storing project source code by default.
From the Vercel documentation found here https://vercel.com/docs/build-step "Vercel tries to automatically detect the frontend framework you’re using for your project and configure the project settings for you. If you’d like to override the settings or specify a different framework, you can do so from the Build & Development Settings section." So Vercel did automatically make a build folder for you. This is ok, because you should always use npm run build to create your build folder and point your hosting to use this folder for production.
I have created the project using npx create-react-app my-app https://github.com/facebook/create-react-app.
When running npm run build I get the following:
70.28 KB build\static\js\2.93539f7c.chunk.js
22.82 KB build\static\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
The project was built assuming it is hosted at the server root. You
can control this with the homepage field in your package.json. For
example, add this to build it for GitHub Pages:
Looks like I need to have server to run the app.
Is it possible to run this locally without any server running? I mean since it is just html,css,js and why would a server be needed here? for what purpose?
Also there is many files generated into the build folder, there is an index.html too, a static folder, so its not like a single bundle.js and a single index.html, it seems more complicated.
Anyone can explain why the build folder is this much files? and which one to consider for running the app?
Thanks
Is it possible to run this locally without any server running?
No
I mean since it is just html,css,js and why would a server be needed here? for what purpose?
React loads content using XHR, which can't make requests to file scheme URLs.
Anyone can explain why the build folder is this much files?
React makes use of code chunking to optimise which data is loaded. This means that JS which isn't used immediately can be loaded later on and not impact the time between initial page load and first render.
By default, Create React App produces a build assuming your app is hosted at the server root.
To override this, specify the homepage in your package.json, for example:
"homepage": "http://mywebsite.com/relativepath"
This will let Create React App correctly infer the root path to use in the generated HTML file.
source: https://create-react-app.dev/docs/deployment/#building-for-relative-paths
So you should just specify your homepage as the current path:
"homepage": "./"
I've got a project where I deploy the same webpack JS bundle to multiple different environments. Some environments use a CDN to serve static assets like JS files, and some do not and just have static assets served from the same root as the rest of the project.
This project also has multiple async webpack chunks, and so I define a publicPath for them to be correctly loaded.
When deploying to non-cdn, webpack works fine with a statically configured publicPath in my webpack config serving everything from something like /static/.
However when deploying to environments that use a CDN, this no longer works for async chunks, because webpack will try to access these from /static/ which means they ask the main app server and not the CDN.
Clearly I can re-build the project with my CDN in publicPath to solve this issue. However, I'd prefer to be able to use just one deployment package in both situations.
My server-side app provides a javascript global detailing the CDN root path, along the lines of window.staticCDNRoot. And this global is also present in non-cdn situations, just pointing back to the app server - so it always resolves to the correct location to load static assets from.
Is there any way I can get webpack to utilize this at runtime so that publicPath becomes window.staticCDNRoot + publicPath without huge hackery?
Or is there a better solution to this issue?
Okay so I was looking for this all day and then found it just after deciding to post here!
Just in case anyone else needs this:
The solution is to define __webpack_public_path__ at runtime when making a production build. But be careful not to use it in development as it can mess up module hot-loading.
More info here:
http://webpack.github.io/docs/configuration.html#output-publicpath
I can suggest to use the plugin at https://github.com/agoldis/webpack-require-from that I have created specifically for that purpose
If you only have a handful of different environments just go ahead and abstract a webpack config (on top of a shared config) that has the different publicPath you need for each. This shouldn't be much of an extra impact on your build pipeline. Then in your application, when you fetch main/runtime webpack chunks from a specific environment/server/cdn, then webpack will pick up the other chunks and async chunks that correctly correspond.
Also, you can work with the assets in your app directly if you need to. You can use something like webpack-manifest-plugin to create a manifest file, which will include all the paths to all your assets with the correct public path. You can request this from your server somewhere in the client at runtime, or you could have your server include this manifest in some config object included in the initial html response sent to the browser.