I'm learning nodejs and vuejs to modify an already created web site.
I installed nodejs, vue and vue-cli and I launched "npm run serve" which apparently start "vue-cli-serve serve"
The problem is that I don't understand what this web server do on files, in this documentation : https://cli.vuejs.org/guide/prototyping.html , it's told:
It automatically infers the entry file in the current directory - the entry can be one of main.js, index.js, App.vue or app.vue. You can also explicitly specify the entry file:
vue serve MyComponent.vue
Ok, but does it run main.js, does it include it into a js file which is the loaded by the index.html on the client broswer.
I see in the browser that the page load a js file named like that: app.23d...js
My question is how this js file is created?
For instance, when the content of main.js is this one:
import './css/icon.css'
Vue.use(VueResource)
Vue.use(VueScrollTo)
what is the output in the app....js file?
It seems it doesn't work at all like php which I usually use on web server
Thank you
Vue uses Webpack to convert your potentially-numerous distinct .js files into bundles with names like app.23d92ab88708...js
From the Webpack documentation:
Concepts
At its core, webpack is a static module bundler for modern JavaScript applications. When webpack processes your application, it internally builds a dependency graph from one or more entry points and then combines every module your project needs into one or more bundles, which are static assets to serve your content from.
I don't suggest trying to get into the details of how Webpack works
This will take a lot of time. If you have an existing Vue project, you are much better off spending your time interpreting that as a Vue project, and accepting that the conversion into the actual app.23d.....js file or files is an automatic process that you do not need to involve yourself in.
It will avoid a colossal waste of time
It won't advance your understanding of how the Vue project works
Whatever you learn about the exact workings of today's Webpack, may be completely wrong about tomorrow's Webpack.
Nevertheless the interface that Webpack provides to you as a Vue programmer will remain constant over future versions.
This is the concept of software abstraction. It is highly advantageous to not have to know how every step of every process works, as long as you know how it is designed to respond to actions you take at a high level.
Horrific thought
I have just re-read your opening sentence:
I'm learning nodejs and vuejs to modify an already created web site.
Please tell me that you are not trying to modify an already created web site where you only have the compiled website available, without the Vue source code? That would be a stupendously painful enterprise.
Related
Background
I have a django app that I want to create an admin widget for. The widget will display text in a particular way (like a terminal). It's so that app admins can see forwarded logs from an analytics process that is orchestrated by django (the app is django-twined).
To do that I want to use something like terminal-kit or one of the other libraries requiring npm install <whatever>
Building the app
The app is built in docker, and I don't want the entire node stack to end up in my production image.
I could use a multi-stage docker build; so install node and a lib from NPM in the first stage, then copy the library from node_modules in the second stage, but this feels unnecessarily slow.
Also, because all I'm doing then is using the raw js static assets that get bundled with the django app, I'm not sure how to go about importing the module (or if this is even possible).
The questions
Can I install an npm module without having the node stack present, and therefore avoid dealing with unwieldy multi stage builds?
How can I then import or require the contents of that module into vanilla javascript to use in a django widget?
Is this even in general possible? If it looks like moving a mountain, I'll give up and just slap a text area with monospace font on there... but it would be nice if log highlighting and colours were properly handled in a terminal-like way.
Can I install an npm module without having the node stack present, and therefore avoid dealing with unwieldy multi stage builds?
You can rollup an npm package using a dev tool like Browserify.
This can be done by rolling up the entire package using something like:
browserify --require terminal-kit
Browserify will parse the package and create a single JS file that you can try loading in the browser. There are some limitations to this so I'd recommend experimenting and exploring the Browserify docs.
How can I then import or require the contents of that module into vanilla javascript to use in a django widget?
You can do this by including a Django template file reference in the backend admin class definition. In the template you'll need to include an html JS source tag that points to the JS script you want to load. Django can include static files when building, you can use that to include the JS file during build time and then a local resource reference to point the template file to the right location.
Is this even in general possible?
Generally speaking this is definitely possible but YMMV. It boils down to the complexities of the npm package and what exactly it is trying to do in the browser.
In steps I would do the following:
Use Browserify to convert the npm package to a single JS file.
Create an html file that loads the local JS file, open this in the browser.
Open the console and see if the commands/context you're hoping to reproduce are working as expected in the browser. You could also write another vanilla JS file and load that in the html file to test.
Include the JS file reference in the Django admin template/widget.
Write custom JS code in the widget that uses/shows the globally instantiated JS script.
This strategy is based off my personal experience, I have had success following this strategy, hopefully it is helpful.
I'm new with React so this question may be a big misunderstanding about how things is done correctly.
I inherit an application build with Python, Django and React.
The React components files are stored in the js folder.
To compile all .js inside the folder, I have to run:
./node_modules/.bin/webpack --config webpack.config.js
This command compiles every *.js, so every modification to the code will be available on the site.
Questions:
Is there a method to get the source mods online without compiling every time?
If there is not a method for check realtime mods, is there a method to compile only the .js I'm modifying?
Am I doing the things in the right methodology or am I missing something?
Thanks!
the main question is: Is there a good way in ReactJs to load a React Component stores on a webserver?
I already reached the goal to do this but I think my way isn't the best.
Let me explain what I currently do:
I have a core project called "dashboard". This core project has the functionality to load javascript via an XHR request. After the request is done, I call window.eval to use this code.
I have a module called "todoModule". This module is the component (or project) stored on the webserver. The todoModule will automatically inject his own code into the navigation bar of the "dashboard" project. The bad thing is, that the "todoModule" has bundled a total size of 1.2MB. And this is too large to load it via an XHR request. I do the bundling via webpack. I already externaled React, ReactDOM, ReactRouter and so one, to use the dependencies of the "dashboard" project. But it is always to big. And the "todoModule" can have his own dependencies, which I dont need in the core project.
I have an other idea to do this:
Store all dependencies in the core project
Build the module with babel --outDir ./lib ./src to just compile the Javascript files without dependencies. The compilied files will have a size of 33KB.
Upload the compilied files on the webserver.
But I don't know how to implement the features, that the module will always use the dependencies of the core project.
Maybe you can help me or give an other solution.
Thanks
EDIT (Solution):
It is not possible to load compiled components from a webserver in a good way. My solution is to deploy a reactjs application anywhere and use postrobot (https://github.com/krakenjs/post-robot) for the communication
I have deployed a Laravel 5.3 application to Heroku. However, when loading /login, I noticed a very slow page load time. The problem seems to be a very large app.js file: /js/app.js. Here is a screenshot of the Network resource panel in DevTools: screenshot- Network panel. The 3rd resource from the top is the offending file.
I am not sure why this file has gotten so large. here is a link to the repository: https://github.com/AshMenhennett/Salon-Pricing.
I wasn't able to post anymore links, so do let me know if you would like direct links to specific files.
What should I be doing to mitigate this issue?
The most obvious thing you can do is to run npm run prod. This will compile the assets for production use. But in most cases, you must be looking at other solutions beyond running npm run prod. If your production file is too large, you must check your dependencies. Remove unnecessary dependencies and ensure that you don't use a lot of external libraries. For example, if you are using bootstrap, you should rely on Bootstrap's alerts in order to show alerts rather than using a Vue package to show alerts. I admit that sometimes you will need to use an external library to make your website interactive but to achieve that, you will have to sacrifice the performance. So your best bet in order to reduce the app.js file is to use the minimal external dependencies in your package.json.
The second thing you can do is use minimum HTML in your components' templates. A lot of components with heavy HTML/CSS will contribute to a larger app.js file. This is yet another approach that will result in a smaller app.js file.
Lastly, you should consider using Vue's component slots to pass HTML contents to your components. This will leave the HTML in your static files and only javascript data (API calls, props, etc.) will be compiled in the app.js file. This is an effective approach to build a smaller app.js file.
Edit: You can remove JQuery and Bootstrap scripts from the bootstrap.js file and can include these dependencies separately. It is always a good idea to have a few more scripts rather than having a very large script. i.e. browsers do parallel downloading and thus using JQuery and Bootstrap dependencies separately is a good idea.
From the looks of your link you've not created a production version of your assets, and currently all the source maps are in your app.js file, which will be adding a lot of the file size, the css and js output are also not compress/minified either.
Assuming you're using laravel elixir, you just need to run gulp --production and this will remove the source maps, compress the js and css outputs, etc.
For people that are using Laravel Mix you just need to run npm run prod to compress and remove source maps from app.js itself.
You need to load the components asynchronously
Webpack has an awesome feature to create chunks of code. The key to this is to use async components. These components get loaded completely asynchronously whenever the component is present on the page you just loaded.
Let's do it.
In resources/js/app.js
I changed
Vue.component('jobs', require('./pages/employer/jobs/Index.vue').default);
To
Vue.component('jobs', () => import('./pages/employer/jobs/Index.vue'));
and in webpack.mix.js
mix.webpackConfig({
output:{
chunkFilename:'js/vuejs_code_split/[name].js',
}
});
Now by running npm run watch or prod each component file is saved public/js/vuejs_code_split/[name].js
And the main app.js is automatically calling those components when required.
I have a production application whose folder structure is much like you would expect:
/project
/css
/js
/php
/fonts
/images
/index.php
I have recently begun learning to use react.js and I would like to start developing new features using react while leaving all existing functionality as is and I understand that react.js can certainly be used this way.
What isn't entirely clear, is how to structure the files in my non node.js project and access them.
For example, I tried searching for this and found this article which proposes the following structure
and states:
Here index.jsx works as the entry point of the application. It uses ReactDOM.render to render App and gets the party started. App in turn does something interesting with Note. If I wanted yet another component, you would simply add it below /components.
Presumably this is a node.js project where index.jsx can call something like require('components/App.jsx');, but how do I achieve the same in my non node.js project.
Consider if I set the following folder structure:
/project
/css
/js
/php
/fonts
/images
/react
/components
/App.jsx
/Note.jsx
/scripts
/featureFoo.jsx
/index.php
Given the above, I'd like to have index.php load react/scripts/featureFoo.jsx which would somehow include/use react/components/App.jsx and react/components/Note.jsx
I figure I could have script tags in index.php to load all of the components then featureFoo.jsx but I feel like there is a more react way to do this.
So
How can I structure/access the react components of my non node.js application?
Im tagging node.js as I feel those users may well bring insight regarding this possibly from having to deal with multiple projects/aproaches.
In order to import/require other modules in a non-node.js (i.e. browser-based) JS application, you'll need to use a bundler such as webpack or browserify.
They work by starting at your "entry" file (index.jsx in your case) and recursively following all of your imports/requires. Then it smartly bundles everything up into a single "output" file, which includes everything your application uses, that you can link in your HTML.
You can also use more complex configurations with multiple entry and output files, or even dynamic loading of "chunks" at certain points in your application. But the above is the most basic use case, and works well for most simpler projects.
These bundlers have some other cool features as well. For instance, with webpack (with additional plugins and loaders) you can:
Write ES6/ES7 JavaScript that gets compiled (via babel) into cross-browser compatible ES5
minify/uglify your output JS
import/require non-js files such as CSS, images, and webfonts, and choose how to process these imports (e.g. pre/post-process your CSS, or optimize your images)
Extract all imported CSS into a single .css file
Use webpack-dev-server (or webpack-dev-middleware) to take advantage of hot module replacement, which makes developing JS apps easier by letting you see your changes take effect instantly in the browser without having to refresh or lose your app's state.
And a lot more. The world of bundlers is a pretty big ecosystem with a lot to learn, but it's totally worth getting into.
A good place to get started is the excellent Survive JS series of tutorials.
However, if you're still learning React, then diving into webpack and the entire ecosystem of JavaScript tooling can be overwhelming. It will probably be easier and a more efficient use of your time to keep things simple at first, and then only get into bundlers etc. after you get comfortable with React.