this course will be about frontend bundler of new generation called vit and because of that it provides much faster developer experience compared to traditional front end bundlers such as web pack so in this course we're going to review most of the V features and we'll be doing it step by step to better understand how V Works which will allow us to use this tool more efficiently so let's get started and install it locally for this I'm going to use package manager called npm so let's copy this command and run it in a terminal this will prompt us to enter project name then we're presented with option to choose which framework we'd like to use we're not going to use any specific framework but instead we'll review with features by using vanilla JavaScript then it will ask us if we'd like to use typescript we will definitely have a lesson about how to use typescript in VD projects but most part of the course will be using vanilla Javas script and at the end we'll see three commments that we need to run sequentially in order to run vid server firstly let's go inside of project folder in here let's run npm install to install all npm dependencies and finally we can start vid server by running npm runev here we will see which address we can use to access our project in a browser so let's open up a new tab and here we see welcome screen of the default with project then let's open up project inside of editor I'm going to use vs code and just to make it easier for us to learn how it works we're going to install helpful VD plugin called VD plugin inspect which will allow us to see how VD transforms our source files so we will get access to such dashboard in the browser and all transformations that we will make with our source files will be visible to us at every step of Transformations this plugin can be installed by running the following npm command in the terminal so let's run it and wait until installation is finished and just to let V know about this plugin we need to add the following instructions inside of V configuration file first we have to create this file in the project route unless it is already created and paste in here all those instructions that we just copied and then we're given with address which we can open up in the browser where our in inst inspector will be available but for now it is not accessible yet we need to restart our V server let's go back to terminal stop development server by pressing crl C then run it again with a commment npm runev and besides with servers address we also see another address where our inspector will be available and we'll see this screen that means our inspector has been successfully installed what it is and how to use it we will be talking about in the next slide lessons and for now let's see which file gets loaded in the browser when we access root of our R server and the file which is loaded is called index.html which is in the project route here we can see that this page also includes main Javascript file which by the way is included as native ecmascript module because here we can see attribute type with Val a module and all our application gets mounted into this deal with an IDE of app so now let's open up main Javascript file and see what is happening inside and right away we can see unusual UTS of CSS file and its VG files which are not supported natively in browsers so if we would be using normal static server those UTS would fail but it treats those UTS in a special way and before serving those UTS to the browser it applies all necessary transformations to make browsers to recognize such UTS where we're going to talk about it in details in upcoming lessons but basically whenever we import CSS files like this V is going to inject all these Styles onto the page and whenever we import assets such as SVG images V is going to expert pass to this file and save it in JavaScript logo variable so then this pass can be used in a normal way for example inside of source attribute as we can see right here to reference corresponding image and sure now this image will be visible on the page it is this JavaScript logo the same thing happens when we import v. SVG file but there is one important difference you may notice that vsvg file is not in our project route it is actually inside of a special folder with the name public and for it this public folder stores all static assets and all static assets that are stored in this public folder will not be processed by VD but instead will be returned to the the browser in its original form we're also going to talk about this folder in detail in upcoming lessons and finally the last import we can see right here is normal import of ecmascript module it is this counter. JS file which provides functionality for the counter whenever we click on that button on the page and we see that the counter increases with a click but we are going to start our explanation of V from the very beginning so let's clear everything inside of main Js file let's also remove counter. JS module which we will no longer use and finally we'll remove all default Styles inside of style. CSS and now we're done with installation and initial setup from the next lesson we're going to start reviewing V's features step by step when we install VD project there are three preconfigured commments inside of package Json first commment starts local development server we have already used this commment in the previous lesson when we started Dev server by running npm randev the second script build is going to build our project for production by applying all necessary optimizations to achieve better performance and there is also one more script preview which starts basic static web server to serve our built application to see how it is going to behave in the production like environment all these three scripts use VD binary which we get by installing VD npm package and this binary is contained within bin folder which is inside of node modules folder so when we use V comments everything starts with this script so let's start reviewing V's features switch over to the terminal and start development server by using command npm run Dev in the previous lesson we have removed everything inside of our main Javascript file so we see a blank page in the browser so let's go inside of index.htm ML and remove this de with an ADF app and on this place let's add heading with some text right away this changes will be reflected in the browser without manually refreshing the page and since our main script file is included as es module in here by using this type attribute we can of course use Import and Export keywords to include other modules and browsers will properly fetch those modules so let's try to import in here arbitrary Javascript file we're going to create this file in projects rout and here we'll just use arbitrary consol loog statement and let's see what's going to happen in the browser when our main application script is requested by the browser browser gets content of this script and once it sees this import it is going to fire an extra request to the server to fetch this module this is native ecmascript feature which is currently widely supported in all modern browsers so we can easily leverage native es modules and once we get a response on request to fetch module with name a we get this content and browser is supposed to run this module so now we're supposed to see this console loog statement in browser's console and sure enough we see this output in here so by now there is nothing special going on and such Imports of es modules are needly supported in browsers so let's try something more interesting for example let's try to use npm package to demonstrate this example I'll be using Library called collect JS let's go ahead and install this Library by using the following npm command and once this library is installed let's go back to docs and here we just need to include this library on the page so let's use this import statement in our main script We'll add it here right after our import of the first module and then let's try to use this library for example to C Cate average from the docs we're going to copy over this instruction and output result in a console and now let's see if it's going to work in the browser and if we would be using normal static web server imports from node modules folder will not be recognized so UT of this collect library is not going to work but in our case we're using VD server so this example worked fine and we got calculated average in a console and let's find out what happened in this case and how V was able to process our import of npm package so whenever we requested our main JS file we can see that VD has done some processing and it transformed the second import when we try to import module from node modules folder let's take a closer look at this import we see that VD transformed pass to this library and once browser receives this transformed inut it is going to request this Library by using the following paths node modules viit depths and the name of our library collect JS and once browser tries to request this file by using the following paths sure enough it gets source code which makes that collect Library work in the browser so VD has dynamically generated folder called vit within node modules folder and here it puts source code of our imported Library collect Js and at the same time VD has done some optimizations to this source code and this is how VD makes it possible to import libraries directly from node modules folder so these libraries will be available to use inside of browsers and this is a big advantage of vit server over basic static server since static server cannot resolve UTS from node modules folder and now let's take a closer look at what Transformations are applied to our source files when when they are served and exactly for this purpose we have previously installed withd plug-in called inspect here we can clearly see how it transforms our source files if we select here module main we can see initial content of this module as we wrote it and transformed code which gets sent to the browser when our browser requests this module here we also see that import of module from node modules folder but if we take a look at Transformations what being applied to another module ajs we can see that the content of this module is left as this so we didn't try to apply any Transformations because this content can be easily recognized by browsers so no extra Transformations are needed in this case it's just a simple consolo statement now let's go back to the editor and in projects root let's create new folder called Source this is pretty common convention to name this folder source which is going to store all our source files and right away let's just move our module a inside of this folder and right after that let's go to main.js here we'll fix the import to import the module with a new name and move these two lines with usage of collect JS Library into file tojs so that the module's file name corresponds to current lesson number and one more time let's see what's going on in the browser when browser requests our main script file with the name main.js it pares content of this file and once it sees this import it is going to fire another request to the server to fetch module with this name and we see this request right here and while fetching content of this file V has done extra transformations to provide support for importing modules directly from node modules folder by doing all necessary transformations to this import statement and here you may have also noticed that we were able to use collect Library by using name collect but here we import this Library under randomly generated name and if we search for this name in this file we can see that it gets assigned to the constant with name collect which lets us use this library in a usual way and finally once browser has fetched source code of collect Library we were able to easily use functionality provided by this library and the ability to use libraries imported directly from node modules folder is a great advantage of VD server over basic static server let's take a look how we can work with CSS files in VD projects right now there is no Styles applied to our page so let's go to main Javascript file and try to import CSS file that we're going to create we're going to call new file 3. CSS and place it inside of source assets folder and here we'll just add some basic styles to see that our CSS will be applied we're going to make background color of body dark gray and text color white and so let's see what we is going to do whenever it is that we import CSS file as we can see Styles have been applied right away to our page and here is how it works whenever browser makes a request to fetch this CSS file VI is going to process this CSS file and generate valid ecmascript module that looks like this so by doing the request to fetch that CSS file we got valid ecas module in a browser and this code contains instructions to inject our CSS code onto the page we also May notice in here that all those styles from CSS file have been assigned to the constant with CSS in a formal string and then this string has been added to the style Tech inside of the head element so let's take a closer look at what kind of Transformations are being applied whenever we import CSS file let's open up our inspector and whenever we request CSS file from with server it basically makes this transformation of CSS code into valid ecmascript module and this is how it makes it possible to directly import CSS files as valid ecmascript modules and here is one more way we can import CSS files so by adding query parameter called in line to this import we can get the content of this CSS file as a string into Styles variable and then let's see what is contain within this variable by printing it in a console and when browser fetches our main Javascript file it sees this import so it makes another request to the server to fetch CSS file but V also sees that this request has query parameter called in line and this is kind of assigned to V that instead of automatically injecting CSS Styles onto the page it should directly return content of this CSS file as a string so in response it's going to generate valid masr module where standard expert will be exporting all the styles from the imported CSS module and if we'll take a look at the console sure enough we're going to see those Styles as a string so this is how we processes CSS files and this is what transformation is going to be applied in this case whole CSS code will be converted to a string and this string will be exported as a default export from the generated ecmascript module and then in our JavaScript code we can do with those Styles anything we want for example let's create new element style let's assign those styles to Inner text property and then we're going to find a head element and append our newly created style element to the head and this way we're going to end up with the same result as if we would import CSS file in a normal way without using inline query parameter as we can see we just manually injected those Styles inside of head element formatting of style Tech will be a little bit different in here but the end result will be the same and this is how it handles CSS Imports let's go back to main.js file remove everything from here and leave only import of CSS file we're going to continue working with CSS in vid projects in the next lesson let's see how we can work with CSS module specification in withd projects first of all we're going to import a couple of CSS files in our main script let's just give them arbitrary names and create these files as with another CSS file we're going to place new files within asss folder and now just to have something to work with let's add here some CSS rules for example we will have heading class which will have the following role color of the text will be orange and in another CSS file we're going to have the same CSS selector but in this case let's use another CSS property font size and set it to 30 pixels and so what will happen right now when we're going to use this heading class is that it's going to apply both of these rules to the element so the color will become orange and font size will be 30 pixels let's just assign this class heading to this H1 element and before we check it out in the browser let's go back to main.js file and import another CSS file 3. CSS this is the file we have already created in the previous lesson and we already know what will happen in a browser when it's going to make requests to fetch these CSS files actually VD is going to convert every CSS UT into valid ecmascript module where all styles will be assigned to a constant with the name V CSS and then this code will also include these Styles as separate Style Elements inside of head element as we can see right here and as a result on the page we see text with orange color and now we're going to go back to the editor and do the following let's include suffix module in every of these Imports and this is going to be kind of a hint for V to treat this CSS Import in a special way so what vit is going to do whenever it sees such UT with word module it is going to apply transformation to to convert this CSS module into valid ecmascript module and this module as a default expert will have JavaScript object with Styles and of course we can import such objects from CSS modules and assign it to appropriate variables for example to style a variable and style B and just to see exactly what we're going to get in these variables let's print each of those variables in a console and in order for this to work we should also rename appropriate CSS files and use module word in names so let's do this rename first module 4 a by adding module word and also do the same with second module for B and if we take a look what we get in a browser when we were requesting every CSS module we see that theit has applied conversion to turn CSS modules into AAS script module but this time it has also converted our original class names into unique strings as we can see and also since we printed exported objects in a console let's just see how these objects look so as a key in here we see our original class name that we have used in CSS module files and as a Val it has corresponding converted class name which is unique per CSS module so on the page we're going to see two Style Elements that include both of these unique class names and every style element corresponds to one CSS module so now we don't have to to worry if we're going to have two equal class names in more than one CSS module because generated classes will be unique and let's see it in action so I'm going to query element with class heading and assign to property class name class of the first CSS module so I'm referring to the first CSS module object Styles a and use class name which is start within heading property as we can see this key corresponds to our original class name but the actual value which is stored under this key is unique class name so by applying only this heading class from the first module we going to get only one property applied font size and another property which makes text color orange which belongs to another CSS module was not actually applied because every class name is unique per CSS module and if I would like to also apply text color I'm going to have to manually assign CSS class from the second module Styles B in the same way by referencing heading property so right now we see that both those CSS rules have been applied because we have manually assigned unique CSS classes to this H1 element and as for Transformations that we makes with our CSS modules we can see that our original CSS module code gets converted into the following code where class name becomes unique with unique HH appended to class name and after after we has applied this transformation it is going to transform this CSS code into valid ecmascript module so after running this code in the browser the Styles will be added to the page and this module also exports object where key is our original class name and value converted unique class name and this is how we were able to import CSS module within Javascript file so we have received default expert into this Styles a variable which contains our original class names as keys and converted unique class names as values and since here we use synex of native Imports of es modules we can just as easily use the structuring and fetch only those parts that we need for example we want FH only class that corresponds to heading let's use here variable heading assign an alas heading for size just to avoid collision with another CSS class that we are importing in here we can also assign unique Alias heading color and then we need to reference these new aliases when we assign these classes to heading element and sure enough we're going to end up with the same result and this is how we can work with CSS module specification in vid projects we have already seen how to import CSS files in JavaScript modules and also in the previous lesson we have taken a look how it works with CSS modules specification and in this lesson we're going to see how it allows us to apply post CSS transformations to CSS Imports and just to demonstrate how to work with post CSS plugins in vid projects we're going to install very popular post CSS plugin which is Tailwind CSS framework so in docs let's open up installation instructions in this case we're installing Tailwind CSS in vid project so let's use page how to install tailin CSS Within withd project and here we can skip the first step because First Step initializes default withd project but we already have a project so let's go directly to step number two and install all necessary packages to provide support for Tailwind CSS the first comment is going to install the following packages Tailwind CSS post CSS and auto prefixer and the second command is going to generate two configuration files one for Tailwind CSS called twin. config.js and another file is post CSS configuration and by the way generated post CSS configuration file already contains necessary plugins which provide support for tawin CSS there is Tailwind CSS plugin itself and auto prefixer to provide support for modern CSS rules in most browsers and now we need to tell Tailwind CSS utility which files will include Tailwind CSS classes and we can do it by specifying value for Content property here we just list pass to all the files with tawin CSS classes and since in our case we're only going to use Tailwind classes within index.html let's just mention pass to this file and on the next step we're going to have to add the following Tailwind CSS directive to our main CSS file so let's copy over these three directives so inside of our project let's create new CS s file 5. CSS inside of assets folder and place those three dires in here and finally after we restart server by running npm Rand Dev we can start using all available Tailwind CSS classes in our source files like this so first of all let's restart our server by pressing contrl C in here to stop the server and run it again by running npm randev let's clear out everything within main.js file and leave only import which includes tellin CSS so we only import 5. CSS file because this is the file where we previously included TN CSS directives and now when browser Encounters this CSS import it is going to make request to our VD server and VD server is going to respond with valid EAS module which means it has converted our CSS file with included Tailwind CSS on the Fly and hold CSS style sheet has been assigned to with CSS constant and then this constant has been used to inject this Styles onto our page as we can see this style includes generated tailn CSS style sheet so let's go ahead and try to apply a couple of Tailwind CSS classes to our heading let's copy over code of this background color from this file and style our H1 heading and in deln CSS the class which corresponds to background color starts with BG and then here in square brackets we can specify Dynamic value of the color so let's paste that hexadecimal code and let's also make text color white and let's better apply those classes to the body element and here we go in Def toes we can see that the appropriate Tailwind CSS classes have been generated and sure enough proper Styles have been applied and in terms of Transformations let's see what transformation have been applied to our initial CSS file as we know our initial stylesheet contains only Tailwind CSS directives so tawin CSS plugin that we have included in post CSS configuration has turned this three directive into full tawin CSS stylesheet and then vid has taken this generated stylesheet and applied another transformation which eventually turned this stylesheet into valid ecmascript module so at the end this code was run in the browser and tawin CSS Styles have been included on the page let's just try to use another Tailwind CSS class to make font size 30 pixels and in a browser in order to see newly generated class we don't even need to refresh the page all modifications are reflected on the page instantly thanks to v hot module replacement feature and this is how we can work with po CSS transformations in VD Pro projects we just need to create post CSS file in our project install all necessary post CSS plugins then include those plugins in post CSS configuration file and it is going to automatically apply all necessary post CSS transformations to all imported CSS files let's see how easy it is to use CSS pre-processors in vid projects and for demonstration purposes we're going to use SAS so let's open up ourain Javascript file and import new stylesheet with the name 6. CSS let's go ahead and create this file in assets folder by the way this will be a SAS file so in main.js let's change this extension on SAS and now we're basically going to use arbitrary CSS rule convert this rule in valid SAS syntax and then let's also switch over to index.html and remove all Tailwind CSS classes that were left since previous lesson V provides support for different CSS pre-processors such as SS Les stylus out of the box so all we have to do is to install CSS pre processor with lu to use in our case we're using sus so let's run this command and install CSS compiler after that we need to restart our development server so let's run npm Rand there once again and in a browser we'll see that those styles that have been specified Within SAS file have been applied that means SAS successfully compiled our source file and it was successfully served to a browser and as a response VD has returned compiled CSS file in the form of string which has been assigned to this VD CSS constant and of course this ecmascript module has run and our Styles have been injected on the page as always within head element and if we'll take closer look at the Transformations that we has applied we'll see that our source sus file has been firstly converted to valid CSS syntax and then VD has transformed this code once again to convert it to valid ecmascript code which will inject CSS code on the page and by the way along with CSS preprocessors we can also use CSS modules at the same time and for this we need to use module word in file name let's rename this source file we have already seen how to work with CSS modules in one of the previous lessons so we're not going to spend too much time on this here let's just see what is going to happen when we import CSS module like this which also has pre-processor code and let's take a look what value we're going to get in this Styles variable by printing it in a console if we leave it as this in a console we're going to get an empty object so let's go back to SAS file and change this selector on class for example wrapper and there we go now this object contains one key which corresponds to class name and the value will be generated class name with random hash and of course CSS rule that corresponds to this unique class name has been injected within head element and now in our Javascript file we can use this class name in whatever way we'd like for example let's manually assign this class to the body element like so and of course in a browser we will see that this rule has been applied to our heading element and this is how easy it is to work with CSS preprocessors in vit projects vit allows us to work with Json files very easily all we have to do to use some Json file in our Javascript file we just have to import it as usual as native ecmascript module and let's see it in action so in here I'm going to import some Json file and accept default export from this module in data variable and then let's create basic Json file with a couple of fields for example name and H this object will describe a person and then just to see what we're going to get inside of data variable let's print it out in the console and check it in the browser and first of all what is going to happen in a browser whenever it encounters our Json import right here it is going to fire a code to our server to fetch this JavaScript module but since this file is not a valid JavaScript module VD has to process this import first and convert Json file into valid ecmascript module and eventually by doing a cod to fetch this file in the browser we're going to get the following in the response so every field of that Json object was exported here separately and additionally the whole Json object gets exported as default expert right here and by printing that value which gets exported from Json module we will get plain alt JavaScript or object in a console with properties name and Ag and as for Transformations which git is going to apply to our Json module we can see that it converts Json syntax into ecmascript syntax which of course allows us to import Json files as normal ecmascript modules in our JavaScript source files and since the default expert that we get is normal JavaScript object we can easily apply the structuring and extract only necessary Fields name and H and sure enough in a console we're going to get value of every field exported separately so this is how easy it is to work with Json files in viit projects in this lesson we're going to take a look at how to import static assets so let's just create new directory in our project we're going to use the following pass Source assets IMG and here we're going to move our image javascript. SVG and now let's try to impert this image in our main Javascript file so I'm going to add import statement and let's just reference that file that was previously moved within IMG folder with the name javascript. SVG and just to see how V is going to handle such image import we're going to print value of this image URL variable in a console and as we can see VD has given us full pass to that image so when our browser requested our main JavaScript file we see that the import of our image was transformed a little bit by adding import query parameter to the end of this pass and once browser has made another request to fetch this file we can see that VD has given us valid ecmascript module with the default expert which points to that image in our project so basically thisas module returns pass to their exported image and of course that pass was assigned to image URL variable which we have printed in a console and now we can do with this pass whatever we like for example let's add new Element image into our HTML file with an IDE of image and then from the JavaScript code we're going to get an image by using get element by ID method and then we can assign that pass to Source attribute so the image will be displayed in the browser and as we can see it worked and in a browser def tools Source attribute contains pass of the exported image and of course that image is shown on the page so once again when we have imported our image in the main Javascript file the pass to this image was saved into image URL variable and then we used this variable to assign to Source attribute of image element and this way image was displayed on the page and besides importing images like this we can also import other file types for example Json file let's try an example here I'm going to import Json file from the assets folder and within this space I'm also going to include URL query Pam like so and now let's see what this Pam URL is used for we're going to print this URL in a console switch over to the browser and right here when our browser has requested Json file by the following address instead of experting Json object as we have seen in one of the previous lessons by adding URL query R to this pass V has transformed exported Json file into valid masri module with the default expert which actually points to imported file but what if while importing images we can receive content of an image instead of the pass to this image so in such cases we can use another query param called row like so and in this case instead of giving us URL to this image within image URL variable V will return the content of the file J javascript. SV and we can see this content was printed in a console so in terms of Transformations if we take a look at javascript. SVG request here we see that the vid has transformed the request at file pass into valid excript module where default expert is the whole content of this image so in this lesson we have taken a look how to import static assets such as images into JavaScript files and additionally we have also taken a look at a few Cod parameters we can use while importing static assets such as URL and row in the rot to VD project there is a special folder called public and this is the folder where we can store all our static assets but of course as we have already seen static assets can be stored in different directories such as source so what's special about this public folder then and the thing is that all static files stored within public folder they cannot be referenced in our source files for for example we cannot import them like this as we are importing javascript. SVG file in here so that means that VD does not process all those files that are stored within public folder let's see an example I'm going to add one more image tag in here and a reference image from public folder with a name v. SVG so at this point our page shows two different images One image was imported directly in our source file and browser has EST at the module which experts pass to the first image javascript. SVG this is the image which was referenced from within our source file so we manually imported this image as a kript module but if we take a look at another image and the way how this image was fetched we will see that in this case browser has requested this image directly by its name as a normal static file and so whenever we want some static assets to be accessible as normal static files so we can reference them by name we have to place such files within special public folder in vid project and by the way all the files that we will store within special public folder they cannot be referenced from within source code meaning that we cannot import them directly as sigas script modules from within JavaScript code and all files that are located within public folder they will not be processed by V during the build so for example if I'm going to will try to build this project right now by running npm run build in the terminal among the build Assets in here I'm going to see that JavaScript image which we referenced in the source code so with while importing this image has made some transformations to it and appended random hash to its name but in this output we don't actually see another image with the name v. SVG which we have placed into public folder and referenced in HTML file and that means vid hasn't done any transformations to v.svg image so what it did instead is it took this image from the public folder and copied it into this folder and this this folder was generated by running npm run build command so this is the folder where it places all buildt files of our project for example we want public folder to be renamed on build folder for such cases V provides us with another option that we can add into the VD config SVG called public deer and in here we specify desired folder name for static assets I'm going to specify build of course after this I also have to rename public folder on build and let's try to run the build Again by running npm run build in the terminal as we can see this time build was also finished successfully and that static file v. SVG was successfully copied from the build folder into our dist folder with a build project so that means that vid has recognized new name for our static folder built and we are still able to reference our static file with SVG from the source code so let's remove that option public deer as well as folder with a build project disc and let's rename folder with static file back to public and just to make sure that we haven't broken anything let's run the build common again and see if project will be built successfully as we can see nothing was broken and built still works and besides these comons npm run Dev to run development server and npm run build to build a project for production initially we also defines another comment called preview which is going to run simple static server ser and this server is mainly used to serve folder with built project files and this way we can check how our project is going to behave by using production build files in the production like environment so now that we have already built the project and generated this folder we can run this npm run preview command to run static server inside of that dist folder let's do so by running npm run preview as we can see this static server was run on Port 4173 and by opening up this address in the browser we don't see any visual changes our project still looks like in the development mode but in fact if we will take a look at the request which fetches main Javascript file we are not going to see any ecmascript import statements in here because during the production build VD has actually taken all the modules and bundled them within one JavaScript file and this resulting Javascript file was fetched in one go in the browser and this is how we can run simple static server to serve all the files from the build folder now let's go back stop this startic server and instead run development server by running npm runev and since we don't need the folder with a build project anymore let's remove it and finish this lesson V ports Import in several modules from the file system by using special function which we will review in this lesson so first of all let's clear main Javascript file let's also go to index.html and remove IMG element with an idea of image and now back to our main Javascript file and in here we're going to write the following let's create constant with a name modules and the special function which VD provides us with is called Globe which we will call on The Meta object and here we're going to specify pass to those modules that should be imported and by the way in here we can also use so-called Globe syntax which is kind of like simplified version of regular Expressions so for example I'll say that I want to import all JavaScript files within folder with a name 10 and I can do so by specifying asteris instead of file name and of course to import these modules first of all we have to create them in our project structure so let's create folder with the name 10 within Source folder and in here let's create three modules first one is ajs and just to see that our modules will be imported we're going to place here simple console lock statement and the same thing we're going to do with the rest of modules second module will be BJs which is also going to contain simple consolo statement and finally third module will be called CJs and in here let's see what we got into this modules constant by printing it in a console like this and as we can see in a console we get an object where every qod this object corresponds to pass to a particular module and the value of each key is a special function which we can use to dynamically load particular module and actually before proceeding any further let's take a look at the transform main JS file which browser has received so once VD has discovered that call to Globe function it has transformed this SK into such form where we can see the usage of the method assign which creates an object where every key of an object points to individual module we're trying to import and as a value for every key it has a function which contains instruction to dynamically import particular module and now we can simply iterate over keys of this object let's do this by using Val method on the object and here we need to pass the object which Val Val we have to iterate over so we're using our modules constant then let's call method for each to iterate over values of the modules object and on every iteration we're going to get a function which we can use to dynamically load particular module and this function Returns the promise so we can chain then call and when the promise will be resolved once our module will be imported as a parameter in here we're going to get the result of execution of the imported module and which is why in a console we have three different log statements and each of these statements comes from modules imported dynamically so on the initial page load browser has instantly requested these three modules as we can see we have requests for every such module in the network Tab and therefore this consol statement was also run which produced those Lo statements in a console and now let's print out the value of the data variable which will receive after promise gets resolved after Dynamic module import so for now we're not going to see anything interesting Within These objects they're basically empty but what we're actually supposed to get Within These objects is the actual data which gets exported from the dynamically imported modules and as of now our dynamically imported modules do not export any data which is why those objects are empty so now let's go ahead and try to expert something from module a we're going to use default expert and expert number two from the next module BJs we're going to expert constant name with value John and right now within those objects which we receive after promise gets resolved first object is going to contain the key default since we use default expert within the first module and it contains value which we expert that number two and the second object contains property name because this is the constant name which we export from the second module with the value John but even though those Imports of modules a B and C are considered to be dynamic they are executed right away when we load the page and now let's try to change our code in such way that these modules will be loaded only after some event OCC course for example on the document object we can register listener for a click event and within this event handler we can place all this code which is going to dynamically import our modules and now in the initial page load we're not going to get any data within the console as we can see no logs are present here but after I click on the document in the network tab we can see that three new calls are being made to fetch our modules a b and c and of course after execution these modules we receive logs in a console as well as the data that gets exported from window those modules and now a couple of words about the configurations which we can pass when calling Globe method so as a second parameter in here it receives configuration object and one configuration option is called eager this option literally disables Dynamic nature and even though based on our current implementation Dynamic modules are supposed to be loaded only after clicking on the document with this eager option set to True our modules will be loaded instantly on the initial page load let's check it out and right away on the initial page load as we can see our console contains three log statements which is a hint that our Dynamic modules were loaded and executed an appropriate Network requests to lower Dynamic modules we can see in the network tab it's these three modules a b and c but also let's see what is going to happen this time when I will click on the document and in a console we're going to get an error saying that module is not a function and this is because we have used eager configuration option with value a true and The Returned modules object no longer contains functions that we can execute to load Dynamic modules and let's see what it contains instead by printing the value in a console so as we can see in here we got an object where every key is passed to a particular module and instead of the value be in a function which we can execute to load module dynamically this time all modules were loaded immediately on the initial page load and as well as in this object we have exported data from those modules for example first object contains key default because first module uses default expert and the second module contains key name because we expert constant with this name from that module and theel a John and as for the Transformations which wi has applied to the C2 Globe function we can see that it converted that call into such three import statements where each import statement Imports particular module and the data which gets exported from every module is being saved as a Val for keys of the resulting object that we store within modules constant and of course the same transformation which is being made on our JavaScript source file we can see if we take a look at our plugin inspector in here and this is how we can use special VI function called glob to import several modules at once but this is definitely not all what glow function can do and in the next lesson we're going to review some additional details about this function let's continue reviewing function called Globe to import several modules at once so in the previous lesson we have reviewed one configuration option with the name eager and in this lesson we'll continue reviewing some other options for example we can also use option called as and in case we specify whether they rot for this option then the object which Globe function will return is going to contain the following every key of this object will still be passed to a particular module but the Val is different because this time it contains content of those modules instead of the function which allows us to load particular module dynamically so when browser were requesting those modules to fetch them as we can see VD has replied with the following content it has produced used validas script module where default expert contains module content in a string form so literally what V has done it read content of every module converted it to a string and returned to a browser but if I'm going to specify value URL for the option s in here this time glob function is going to produce the following result we still get an object where every key is a passed to individual module and the Val this time is absolute pass to those modules so as a response to calls which fetch those modules in the browser VD has return the valid masr module where default expert is pass to that module and now let's try to do the following I'm going to add an expert of constant name into every module in the first module this constant will be equal to Jane the second module B already contains this constant with value JN so let's at the same constant into module C and the value in here let's say will be JY and I'm also going to place default expert into every module the first module will expert letter A as a default expert the second module will export letter b and the third module will export letter C and then back to our main Javascript file let's remove this configuration object that we're passing to Globe function remove the comment from this channel of code and this time let's use one configuration option called import and what this option allows us to do it lets us specify name the expert which would like to import while importing modules in bulk by using glob function so for example if every module we're trying to import in bulk contains some named expert instead of importing anything else we can literally specify a particular input that would like and since all our module expert constant with a name name we can specify this name in here and since we have already specified that every import should contain import Cod name that promise which will be resolved after dynamically Import in module will contain this data so let's rename this parameter on name and use it to print it out and there we go after every Dynamic module gets fetched and executed we also see the value of the name variable in here which contains names and if for example I only want to import default expert we can literally mention default in here and this time instead of names we're going to get Val experted by default from those modules and let's take a look at one more combination of configuration options we're going to use eager option with value true and import option with value name and by now we already know that by using these configuration options we disable a dynamic nature of importing modules as well as we specify that we'd like to import only imports called name and as a result we're going to receive such object where every key is a pass to individual imported module and as a value for those keys we receive values of the named experts called name so all our three modules a b and c were requested and fetched on the initial page load and now let's also take a look at the transformation what bit has applied to glob function call so right here we can see it was transformed into three static Imports where every import Imports only one piece of data called name and down here all this data gets GA it within one object and this object gets assigned to modules constant which at the end gets printed to the console so as we can see this glob function which VI provides us with to load several modules at once is pretty powerful and lets us import multiple modules in several different ways in this lesson we're going to check how to work with a jsx specification in V projects and additionally we're going to implement our own custom jsx specification so let's get going first of all we're going to clear out our main.js and in here we'll add Only One Import I will import the file with the name 12. jsx and right away let's create this file within Source folder and as an example we're going to add some arbitrary jsx code within this file so let's create new constant template and then let's use the jsx syntax and specify arbitrary jsx markup kind of like we do in react projects when we create components here I'll create a du with the class wrapper within which I'm going to put Tech p and finally this paragraph will contain anchor Tech and just to have some Styles applied to our markup we're also going to create CSS file with the name 12. CSS and import it right here and as a Content let's just copy over all content from 3. CSS and put it within 12. CSS and just because we're using CSS class called rer in our jsx mark up let's rename this selector on wrapper and so that now we expert constant with a name template from this module let's go back to our main.js and apply the structuring to this import and extract only constant with a name template and I'm also going to use console loog statement in here just to see what we get within this variable after that we're going to get console error because currently our project cannot recognize Js syntax so we need to enable a jsx support and to convert jsx syntax into JS syntax V uses another bundler called es belet and it also lets us specify a couple of options within VD configuration file to kind of Define our own jsx specification and this way we're going to teach we how to process our jsx syntax so let's go back to the file with jsx code and here I'm going to create new new local function with a name create and later we will specify this function as a jsx factory function which is going to be responsible for creating D elements based on our jsx elements let's do this right now so let's open up V configuration file and in this configuration object we're going to specify options for ESU within this internal object and for now the only option that we need is called jsx Factory and this is the option where we need to specify our function name which will be responsible for processing jsx elements so if earlier we have created the function with a name create I'm going to use this name in here and when V is going to process our jsx code for every tag name it is going to call our custom function create and it will pass three additional parameters first one will be element which will contain the tag name the second one will be an object with a attributes that we have specified on that tag within jsx syntax and the third parameter will be content that we can put in between opening and closing text so before going any further let's just see what we get in all these three parameters I'm going to add another console loog statement and print out every parameter and this function will be called three times one time per tag we have used within jsx syntax so the first code to the create function has received three parameters with the following values the element parameter equals to T name a the attributes that we have specified on the anchor Tech consist of only one attribute called hrf and finally the text that we have specified for this anchor element is link the second call to the create function has received parameters with such Val when the first one corresponds to the tag name and the other two for now do not contain any vales and the reason to that is because we haven't returned anything from our Factory function yet and as a content for a paragraph element we use another element which is Anor Tech and finally these are the last set of three parameters that we get after calling create function third time because the root element of our jsx markup is div which has only one attribute class with the Val upper and because we haven't returned anything from our Factory function yet the third parameter which is supposed to be a content of this div element holds value undefine it for now and now we're going to get to fixing it going back to our create function in here I'm going to create new constant called node and based on the element name what we receive as the first parameter into this function we're going to use native Dom API and create Dome node by using Create element method on the document object like this and now that we have our Dom element created we need to take attributes object which we receive as a second parameter into this function and iterate over all the attributes within this object and to iterate keys and values of this object we can use JavaScript method entries and here we're passing object name which we' like to iterate over and if this object will be null we're going to f back to an empty object and this entries method is going to produce array with pairs key and value that are contained within attributes object so we can easily iterate over this array and as a first parameter we're going to destructure these pairs the name variable will hold attribute name and the Val variable will hold its Val and finally in here by using another native Dom AP Pi method called set attribute we can set attribute with a name stored in the variable name and assigned value stored in variable value like this and down here we also need to check if SE parameter also contains value which is supposed to be a content for our Dom element and if this value will be a string we're going to create text node based on this string by using Create text node method and pass received content into this method and then reassign resulting text element to this content variable and finally we need to append this text element into that Dom element we have previously created so let's use a pen child method and pass variable content as the first parameter and eventually we're going to return create a d element from this function so right now let's check one more time what values we're going to get within every parameter that we print in here the first code to the create function has produced the following result as the first parameter we still get anchor element the second parameter is object with attributes to this anchor and the third parameter will be content for this element and then when V sees paragraph element within our jsx markup it is going to call create function with this element as the first parameter and since we have not specified any attributes on this P element the second parameter is empty and finally just because this paragraph element contains another element a as the third parameter we have received D element which corresponds to an anchor and this anchor element was created when calling that function create that we have implemented earlier and finally our GSX markup also contains another element called div the create function gets called for this element first parameter will be element name which is Du the second parameter contains attributes of this element we have specified only one attribute with the name class and just because this element also wraps another element paragraph As a Content within the C parameter we receive this paragraph element so now let's go back to the create function and remove this console loog statement and as we can see in our main.js file we have another console lock statement which prints out content of the template variable and this template variable is supposed to hold Dom structure which was created based on our initial jsx markup so if we take a look in the browser we will see that this template variable holds a root element of our jsx markup for now it is represented as a Dom element but to see the whole content as text we can use another Dome property called outer HTML let's use it in here and check conso again and now we see full string representation of our jsx markup so this whole jsx markup that was specified in here it was properly processed and turned into Dom structure and then we have printed out its string representation in a console and now what we're going to do instead of printing this markup in a console we're actually going to create another div element in our index.html with an identifier of up and then let's goad and add this hmark up in our page so I'm going to use Query selector to select element with an idea of app then let's call append child and as a parameter we specify D element we wish to append within element with an IDE of app and as we can see in the browser new element was appeared on our page which is that whole converted jsx markup added within up element but right now we can't really see the link well so let's go ahead and change Style we're going to make the text color white for this link and there we go now we can clearly see the link and what we're going to do next is to extract this Factory function create and move it in the new module we're going to create new file called 12- create within Source folder and put that function in here and of course we need to expert this function from this module but after doing this change we're actually going to get error in a console saying that create is not defined so right now whenever we're going to use a jsx markup we also have to import our Factory function create from the new module 12 create. GS let's add a proper import statement in this file and after this as we can see everything is working again but yes having to import this create function every time we want to use jsx markup is not very convenient so we can use another trick and specify option with the name jsx inject in the es build configuration object and here we can Define what content should be automatically added to all jsx files so we can add in here that import statement of create function so we don't have to import it manually over and over again in jsx files let's just specify an absolute pass to the module which holds our create function and now even though we haven't explicitly imported create function in jsx file we still can see that our jsx code was properly processed and resulting jsx structure was injected into the page that is because VD has automatically added proper import statement which Imports our Factory function create at the top of the GSX file and by the way every usage of the jsx element in our jsx markup was great into such function calls of our Factory function create with proper parameters depending on the GSX element so in this lesson we have learned how to write our own jsx specification and use it in vid projects let's talk about typescript supportting vid we're going to use a very basic example just for demonstration purposes how to integrate typescript into vid project so I'm going to create a new file with an extension TS let's call it main.ts and in here we're going to declare a function sum which basically is going to sum up two numbers it will accept two arguments of type number A and B and it's supposed to calculate the sum of these numbers and eventually return number so in here let's just sum up two arguments a plus b and down here we're going to add console log statement to print out the result of calling this function sum with arguments one which is number and the second argument will be two but this time it will be a string and before checking it out in the browser we of course how to include this file to our page and by the way it allows us to include typescript files directly within HTML files like so so once it's done let's switch over to the browser and surprisingly we don't see any errors in the console and as a result in a console we have number 12 which is the result of executing that some function so as we can see after browser loads our file main.ts it receives the content where all types have been stried so that means VD has applied transformation to this file to remove everything related to typescript and leave only valid JavaScript code that can be run in a browser so that means that vid hasn't done any static type checks and instead only converted typescript syntax into JavaScript syntax and which is why as a result of executing this function we got 12 because instead of summing up two numbers JavaScript has concatenated them and there is actually a reason why it doesn't do any static type checking when converting typescript files into JavaScript files and this reason is a speed because to do full static type checking will actually drastically delay the whole build process so what we'd recommend us to do instead if we want to run static type checking is to separately install typescript compiler we're going to to do it right now so in a terminal let's run npm install typescript and then we're going to use this compiler to separately analyze our types script files and apply type checking so in our package.json we're going to add one more script within script section with the name TSC and what this script will do is basically run typescript compiler but in our case we don't need to transform any typescript files into JavaScript files instead we want only run static type checking since this will be done by V and instead what we want to do is to actually run static type checking so in here for typescript compiler we're going to use option called No emit which is not going to produce any JavaScript files and instead we'll only run static type checking and now if we try to go ahead and run that script by running npm run DSC we're going to see the following error and to fix it we have to uh typescript configuration file within the root of the project with the name TS config.js and in here the only option that we have to specify is to actually show typescript compiler where our source files are stored so let's add root deer option with the value dot which is kind of a pointer to the root directory of our project so right now if we run the same common again npm run TSC this time we're going to get a different error and this is actually the error that we expect that we have some type mismatches in our typescript file so right now our typescript compiler works properly and gives us hints whenever we have type mismatches like this one but actually a running types script compiler like this is not going to rerun it every time we're going to make change to our source file so to make typescript compiler watch our source file for changes we're going to run the same command npm run DSC but this time we will also add flag watch and from now on anytime we're going to make a change to our source files for example let's go ahead switch over to main.ts and make a change by fixing this type error and now that we don't have any type errors within this file if we take a look at the types scrip output we can see that typ scrip compiler was rerun and this time there are no errors and warnings being reported so when it comes to running typescript in VD projects this is one of the V recommendations to run typescript type checking in a separate process to prevent deferring main VD build process but if we actually want to fully integrate typescript type checking process within VD build process there is a special plugin for it called with plugin Checker and this plugin allows us to fully integrate typescript type checking into vid build process and after that all typescript related errors and warnings will be shown directly in the browser and if we wish to use this plugin the first thing we need to do of course is to install it by running the following command so let's switch over to the terminal paste here that installation comment and wait until the installation process finished and after installation is finished next we have to configure this plugin by adding some instructions into our withd configuration file so first of all let's add this import statement I'm going to switch over to my V.C config.js and right below the inspect import statement I'm going to paste new import statement for withd plug-in Checker plugin and one more thing to do to configure this plugin is to actually copy this function call and paste it into plugins section down below like this and this is actually all what's required to fully integrate typescript type checking within V build process so right now we're going to go ahead and get back that type check in error by converting this argument to string this time during VI build process we're going to see that the typescript error was appeared within the browser so as we can see from now on every typescript error will be shown directly in the browser and of course if we go ahead and fix this error and check the result in the browser we no longer see any typescript errors and now within such setup we no longer need to run types script compiler within a separate process so let's stop the previous process that we have previously run in a console by pressing controlc because typescript will notify us about any type related errors directly in the browser now that we know how to integrate typescript with the invit project in this lesson we're going to see how to integrate es link which is a static analyzis tool for JavaScript so let's get started and in our main. ES file we're going to add one es link violation let's add a semicolon after this function declaration and since we're going to have to make es link analyze typescript files there is a special plug-in for it that we can use called typescript es link this tool basically enables es L support for typescript and as always the first thing we have to do before using this plugin is to install all necessary dependencies so let's copy over this commment and run it in our terminal on the next step we will actually have to create configuration file for eslint with the name eslint RC do CJs and paste there the following content so in my editor I'm going to create new file with this name paste here all the content I have just copied and then again let's go back to the browser and as a third step we are ready to run our es l so to execute es L we need to run npx ESL and as an argument into this comment we specify the folder where es link should be executed in our case it's fine to specify a root folder of our project so I'm going to use dot let's execute this command in a terminal and as we can see as a result there are a lot more errors as we have initially expected and among all these errors we also can see that error we have made intentionally by adding semicolon to the end of the function declaration and by the way the rest of errors are coming from analyz and JavaScript files so so we need to ignore all the JavaScript files and run yesl only within typescript files and to tell yes L which files it should ignore we can create special file for eslint called eslint ignore and here we can list those files that should be ignored so to ignore all JavaScript files we can use the following notation asterisk do JS so after that if we're going to execute npx es lint again we're going to see only one error which is that error that is coming from our typescript file where we have intentionally added semicolon to the end of function declaration so as we can see to run ESL checks in withd projects we need to start a separate ESL process alongside our main VD build process and this is also recommended by VD to prevent deferring main build process but if you don't want to do this and prefer that VD will run es link during the build process we can achieve it by installing the following plugin with plugin Checker we have already used this plugin in the previous lesson when we were integrating typescript within vid project but besides of integrating typescript this plugin is also capable of integrating other tools and one of such tools is as link and this time we're not going to install this plugin again since we have already installed it in the previous lesson so in here let's open up documentation to run eslint and the first thing to do before running eslint is actually install eslint executable on a system and then we're going to make V use this executable to run es L checks and to achieve it we need to copy the following lines go to our re configuration file with config JS and paste those lines in here like this here we're basically specifying the command which will be used to run as L and as we can see this command also contains P to files that es Lane should scan and since in our case types script files is located within the root of our project let's correct this pass by removing Source folder and after this if we open up our browser again we're going to see e lint error in here so our es lint integration works perfectly and now every time wi is going to build our project at the same time is going to run eslint analyzer and show all eslint errors in the following form and by the way the same output we can see in the server locks in the terminal top where we executed npm runev command and now just to see if this error is going to disappear we're going to switch over to main.ts and remove this semicolon from here going back to the browser again and this time we don't see any es lint errors and of course message saying that no errors were found appears in the logs right here and this is how easy it is to integrate es lint into VD projects VD offers handy feature called pass aliases so let's see how it can be useful for us I'm going to clear out our main Javascript file main.js then let's just go ahead and import this CSS file into our main GS file and of course to import that I'm going to have to write down the whole pass which leads to this CSS file like this and then let's add one more import and we're going to import this image so here I'm going to have to write the whole pass to this image which is contained inside IMG folder and then inside index HTML I'm going to add another IMG Tech to display that image but for demonstration purposes we're going to use JavaScript for it so let's select an element by an ID of image and assign the URL of an image to the source attribute like this so before switching over to the browser we also have to change the extension of our main Javascript file from DS on JS and now let's see how it looks in a browser so first of all the imported CSS file was inserted onto the page in this style tech and as we can see our JavaScript image is also displayed on the right side but there is a chance that over time our project will become pretty large with lots of different Imports and those Imports sometimes can be pretty long and just to avoid always mentioning the whole pass whenever we need to import some module that allows us to Define so-called pass Al's by using which we can drastically shorten our import pass so let's just apply pass LSS for this two UTS as Al I'm going to use add sign and soon we're going to map this character to point2 source as its folder and to Define our own P LS we have to open up VI configuration file and in here let's add another configuration key called resolve which will be an object with one more property called LS and in turn this will also be an object here we need to define the mapping between our pass ls's and actual P that these Alis will be pointing to so in here I'm going to Define one Alis that I have used previously it's this at sign and as for the pass which this LS should be pointing to I'm going to use node GS helper called resolve to resolve the pass to the folder Source assets as the first argument to this method I'm going to pass the current directory name where this configuration file is located and we can get it by using de name magic variable and as a second argument we should specify our folder where our P LS will be pointing to and at the top let's just quickly test this out I'm going to import this pass module and write console log statement and then see what is actually be printed after calling that resolve method with those parameters so in order to see this lock I'm going to have to restart our Dev server by running npm run Dev and right here we can see that pass that was printed by that method resolve and it's exactly the P that we need so our P LS will point to as a folder which is located inside of source folder and now in the browser I'm not supposed to see any changes so as we can see the Styles have been properly applied and the image is also displayed so that means that our custom alas was properly configured and while importing those modules vid has replaced that alas with the proper pass that that alas points to and in our case it is the assis folder inside of source folder so at the end let's go back to our configur curation file and get rid of this console log statement and this is how we can leverage p ls's in order to avoid long passes while importing modules in this lesson let's talk about environment variables and how to work with them in vid projects so we'll start with removing everything from our main Javascript file and in here all I'm going to do is actually print only one value so V exposes all environment variables to the client code under a special object which is stored inside the import meta object so if I'm going to print the value of this object in a console then in the browser we will see that this object already contains some default environment variables for example mode environment variables contains mode in which we have run V whether we have run development server by using npm runev or production build by using npm run build and now if we're going to go ahead and build this project by using npm run build and then open up the build project in the browser by running npm run preview then after opening this URL in the browser and taking a look at those environment variables we will see that this time value of the environment variable mode was changed on production as well as value of prod variable now it's true because now we are viewing build project in the browser and next let's see how we can Define our own environment variables and to do so we have to create the file called EnV and in here we can list all the variables that we need as an example I'm going to create a couple of environment variables with API URL and with another wire and for demonstration purposes let's just assign random values to each of these variables my Dev server is still running so let's open up the browser and see the result and this time in that in the object we have two more variables those are the variables we have just declared inside the EnV file and what's really important while declaring those environment variables in order for them to appear in this object we have to start the name of every environment variable with a special prefix which by default is V underscore because if we're going to try to create another variable without using Us in the prefix for example secret and then let's take a look if this variable is available in the console we will find out that this variable secret is nowhere to be found and this is intentional Behavior because every environment variable which we're going to declare in the environment file will be potentially included in the build project and those variables might contain some sensitive information such as database password and to prevent us from accidentally exposing those enir environment variables to the public build V forces us to explicitly use prefix in environment variable names to manually choose which environment variables should be available in the client code and by the way the prefix can be easily overwritten so to override the default prefix we can go to the configuration file with. config.js and the option that we need to overwrite the prefix is called invvy prefix and here we just specify desired prefix and this time by looking at the environment variables again we will see that none of those variables we have previously defined is visible in here and that makes sense because since we have changed the prefix we also have to change this prefix when declaring those environment variables so I'm going to quickly change this prefix on our new prefix and now as we can see those custom environment variables are back so this is how we can Define custom environment variables to be used in our client code by creating environment variable file with the name EnV but since V can run in multiple modes we can declare many such environment files for example if I only want some variables to be available in the production mode I can create the file do envy. mode name in this case it will be production and since by default when we run the build command executing npm run build it runs in production mode so that means these two variables will only be available when building the project for production so let's run the npm Run build and then npm run preview to open up the build in the browser and this time we see that these environment variables contain those values that were earlier specified in the file. env. production and if we switch over to the first tab where my development project is still running here I'm seeing that those two variables have different values the values from EnV file and when we start development server by running npm randev V runs in development mode but we are not limited to only those two modes development and production we can use as many modes as we wish so for example for some reason I want to build a project for a different mode let's say for St in and this build should have different values for some of the environment variables so so to do that I will just create another environment file EnV and then following the same convention do environment name in this case it will be called envy. staging in here just to demonstrate I'm going to modify values of these two environment variables and now we will try to build the project by using this stag in mode so to specify the custom mode that V should use while building the project we need to write this right after npm run build we use two hyphens then another two hyphens mode this will be an option Name by using which we specify custom mode and then we just specify our custom mode name stag in and this time let's take a look at the values of those two variables and now let's open up the build in the browser by using npm run preview and take a look at those two environment variables so as we can see these environment variables have taken their values from the file.in v. stag because we have just built a project with using our custom mode staging and now in our inspector let's take a look at the transformation that itd has applied to this line when we are printing all environment variables in the console so basically took this line and assign an object with all environment variables to to the property. EnV and if we take a look in the browser it will be more clear so let's take a look at the content of the main Javascript file and right here we can see that an object with all environment variables was assigned to NV property and this way those environment variables are accessible in our client code and besides accessing those environment variables in the JavaScript files we can also access these variables in HTML file so for example let's print out the value of this app API URL variable in the index.html and in order to print environment variables in HTML file we just use a simple notation between percentage signs with specify variable name in this way this variable will be printed on the page so in this case since I'm running the development server then this environment variables value was taken fromt EnV file but if we're going to go ahead and build a project for production by using mpm run build and then take a look at the page here we see a different value because this value has been taken from environment file which corresponds to production mode called env. production because as a reminder VD executes the build in production mode but keep in mind that in order to use these environment variables in the client code we have to use the prefix in their names the default prefix is vore but in our case we have overwritten this prefix on up underscore and one more thing that is also worth mentioning regarding environment variables is that we can also specify these environment variables while executing VD commments for example here I'm going to start development server and at the same time I'm going to declare environment variable up API URL and by declaring environment variables in this way it will overwrite all those environment variables with the same name that were declared in any inv file so if I open up development server in the browser we will see that the value of that environment variable will be exactly the one that we have specified in the terminal while executing npm randev commment because that value has over written any values specified in any EnV files and that is how we can work with environment variables in vid projects besides generating bundles for single page applications V also allows us to generate multiple bundles for several pages one bundle per page and in this lesson we're going to talk about how to actually generate several bundles for individual pages and to demonstrate this let's just do a little preparation so for example in our main index.html file I'm going to add a heading called index and also I'm going to add here a link which is going to redirect it to a second page called login and now I'm going to copy over all the content of this file and create our new page so in the root of our project we're going to create a new folder called login and in here I'm going to add another Javascript file which will be a script for our new page and I'm also going to add HTML file for the login page so here I'm going to paste everything from the index.html and a few values to differentiate this page let's just change the title text here on login as well as the H1 Tech and the link on this page will point to our main page index and of course let's also properly include Javascript file to this page by specifying the proper PA to login. jscript which is contained inside the login folder and then let's also edit the title on the index. HTML page and now let's run our development server by running npm randev and check the result in the browser so here we can see our main page index.html since we have referenced the root pass and if I'm going to click on this link we're supposed to be redirected on the second page which is login and this is exactly what is happening So currently our project contains two separate pages that are completely independent of each other and between navigating these two pages browser actually makes full page refreshes so now let's see what is going to happen when we build this project for production let's switch over back to the terminal and run the commment npm Run build and here as we can see VD has generated only one page index.html but we also expected another page login to be generated as well so let's check the result in a browser and then we figure out why it didn't generate login page so here I opened the build application and if I'm going to try and go to login page as you can see the page didn't change even though the address in the URL bar was updated and this makes sense because VD has generated only one index.html page when building project for production and when we are trying to navigate to the page which doesn't exist we are redirected to the main page and the reason why V didn't generate the login page is because we are missing some configurations to tell it that we actually have more than one page in our application so to notify it about several pages in our application that it needs to generate Pages for we need to add some configurations inside VD configuration file so in here let's add an object built within which there will be another object rollup options which will contain in turn another object called input and finally in this object we're going to list all the available pages in our application and currently we have only two pages so let's specify these pages in here we'll call these Pages Main and login and now as well as for the keys we have to specify the full pass to HTML files or these Pages let's use function resolve to generate absolute pass to our template index.html and the same function we're going to use to generate passs for the login page but here let's also specify proper pass since login page is contained inside of login folder we have to mention this folder in the pass like so and before building our project again let's add an import statement for the resolve function from the standard nodejs module pass and now switch over to the terminal and run npm run build again and let's see what pages have been generated in this case and this time as we can see besides our main page we also see that the Lin page was also generated and if we take a look at the generated folder with our project disc in here we can see an HTML file which corresponds to the login page so now if we're going to preview this project in a browser and try to navigate to the login page in this case indeed we were navigated to the login page but please also note that there is no JavaScript bundle fetched for these Pages even though we have those JavaScript files imported in these templates and actually when we run npm run build the JavaScript bundles are not generated one more time just to make sure that we are including proper scripts on HTML Pages our main page as well as login page so the reason why there were no bundles generated for these JavaScript files is because currently these two files are empty and just to make build generate Jo bundles as well let's just add arbitrary statement in here for example let's console log something in the main.js as well as in login.js and now let's regenerate build project again and this time in the list of all generated files we also see a couple of JavaScript files one Javascript file for each HTML page and now we can use all capabilities of it inside these JavaScript files to continue our development and generate proper JavaScript bundles for every HTML page so let's try it out for example let's assume that we have to import some CSS file well not actually CSS but let's use SAS as an example and I'm going to create this login dosas file and put here some arbitrary Styles just to make sure that while importing This Ss file these Styles will be properly applied to the page so I'm going to make background color of the body Brown the text color will be white and Link text will be white as well and the same sus file I'm also going to create for our main page let's call it main. sus paste the same Styles but to differentiate these two pages let's change background color on Indigo so now let's not forget and also include this main dos file inside our main script like so and now before generating the build we actually have to do one more thing in order for V to compile our sus files we also have to install SAS preprocessor itself so we are doing this by using npm let's install SAS compiler and now if we're going to start our development server by using npm rundo and take a look at the browser we're going to see that those Styles have been properly applied to the page which means SAS was compiled success sucessfully and if we'll switch over to the main page we can see that background color changes because we have two different stylesheets for these Pages index and login and now let's see how everything looks when we build the project for production by running npm run build and then again I'm going to run npm run preview to open up build project in the browser and here we also can see that styles were applied by the way there is only CSS file fetched as we can see in the network tab and there is no JavaScript bundle for this page and again just because our Javascript file contains only SAS import it didn't actually generate JavaScript bundle at all so just to make sure that it's going to generate those two bundles let's add arbitrary JavaScript code in each of these files I'm going to add basic consol lock statement here as well as inside login.js and once again we're going to rebuild the project and run the preview server and switch over to the browser and this time in the network tab we can see that besides fetching CSS file there is also a request for fetching JavaScript bundle as well so everything is properly working and this is how we can generate several JavaScript bundles for multiple pages in case we're building multipage app and the most important thing when it comes to generating several bundles for different pages is to actually specify proper config inside of VD configuration file and particularly what we have to do here is to actually provide a mapin between all our pages and absolute pass for template files of those pages and then when building project for production VD is going to make sure to generate separate JavaScript bundles for every HTML page vit also has mode which allows us to create libraries and in this lesson let's see what tools V provides us with to create npm packages so for that we need to do a little preparation first let's create an empty folder 18 and then switch over to this folder in our terminal and here I'm going to create two vid projects first one will be our client application which is going to import the custom package we're going to create and the second project will be the library itself self so let's start with creating the first client application let's run npm create V latest to scaffold default V project I'm going to call this project simply up we are not going to use any Frameworks so I'll go with an option vanilla JS and also we will not use typescript and now right next to the app folder let's create another vid project which is going to contain the library so let's run the same comment npm create V latest I'll call this project leap and basically make the same choices we'll use vanilla J without using typescript so now let's just open up folders with these projects in a separate terminal TPS and then we can start working on our npm package so let's open up main Javascript file of our library from here we're going to remove everything and install all npm dependencies by running npm install next just to make sure that our application can be open in a browser let's run development server by running npm randev switch over to the browser and make sure application is loaded everything looks good so let's start creating Javascript file which will contain functionality of our package I'm going to place this file inside the source folder and the file will be called index.js so the package we're about to create will contain only one utility function called plug which is going to accept array of objects as the first parameter and the name of the key which will have to extract from every object from the array is the second parameter and in here we're going to Loop over every object in this collection and extract key pest as a second parameter fi and eventually this function is going to give us an array which contains only values of the specified key and just to test out this functionality we're going to create an array of objects for example let's create array of users where every object will contain two keys name of the user and H I'm going to add three objects in this array and then populate each field with random data let's do the same for the h property and down here I'm going to Brint the result of our function plug we'll call this function with our array of users and the property we need to extract will be name and now in a console we're supposed to receive an array which will consist only of the user names and of course to execute this script in the browser let's reference it from index.html and as expected we can see an array of usernames but of course since this project is intended to be an npm package we need to build this project as npm library and we need to tell it that our project is actually the package that other users can install so let's create configuration file with config JS an expert configuration object so let's add object object built within which there will be another object liap and by specifying this lip object we are informing with that our project is actually the package and with has to build this project differently so the first option in this object is entry which will basically point to the Javascript file of our package let's use function resolve to resolve the absolute pass to JavaScript file index.js and then let's assign name to our package I'm going to call it plug and also let's specify another option file name and this option will tell it which file name it should assign to the final bundle script of our library as always let's go ahead and write down an import statement for the function resolve that should be imported from the standard node.js module pass and then all that code that was used to test our function we are going to comment out because this is not Cent application so we're not going to use our function plug in this project but instead it is intended to be used by other users by installing our package into their applications and now it's finally time to build our package so in the terminal let's execute npm run build and looks like I have specified wrong pass to the index file let's quickly get back to V.C config.js and fix this pass the folder name should be source so right now after I'm going to build this project by running npm run build we can see that VD has generated two assets those are built files of our package and the reason why there are two files is because VD has generated two versions of our package the first version will be used when users will import our package by using EAS create modules and the second version will be imported if users will use function required while importing our package so now let's take a look at the content of these files firstly let's open up L.G which is inside of this folder here we can only see the code of our custom function which was minified a little bit and then this function was exported by using LS plaque and this file is what's going to be imported when users are going to import our library by using native ecmascript module syntax and now let's open up another file plug UMD CJs so as was said before this version of the library is going to be imported when users are going to use function require to import our library but this is not all and in order to make our package so that it can be imported we still have to do some tweaks inside package.json so here I'm going to assign different name to our library let's call it plaque then we're going to have to specify a couple more keys in this object and specifically those keys are Main and module and by using these keys we're specifying pass to the build files so when users are going to import our library by using require the file that should be imported in this case we're specifying under the key Main and in case of the Native ecmascript modules we're going to import file plug. JS and now I'm going to have to specify another object experts with almost the same content since our library is exposing Only One Import meaning that it has only one entry point let's specify this entry point and here we have to use a couple more keys import and require and these keys will also contain P to the files that have to be imported in case we're using ecmascript modules or function require to import our library so now everyon is ready to actually start using our library in our client application let's go to our client application and open up main Javascript file let's clear this file and then we have to somehow import our library into this application without actually publishing our package in the npm registry we are actually also going to see an example where we will publish the package but it will come in one of the next lessons and for now I'm going to make our library globally available in the operating system and npm allows us to do that by executing the following commment inside of that library that we have to make globally available and this command is npm link so I'm going to execute this command in the route of our library project and then later I will be able to link to this library from our client application but for now let's switch over to the route of our client application and install all npm dependency so now I need to get the code of our library in the node modules folder of our client application and since we have previously made our library globally available in the operating system we can simply link to that Library by running npm link and the library name in the root of our client application and right away we can see that this comment has created the link with the same name as our library and this link points to the source code of our library and finally it is time to test the functionality of our package in this application so I'm going to start development server and now it's finally time to test the functionality of our package from our client application and to do that let's just copy over that commented code we have previously put in the Javascript file of our package cut it from here and move it inside main.js of our client application ation but of course here this function plug should be imported from our custom package so let's write down an import statement for this function and import this function using our package name plug the same name which is used inside node modules folder and by actually importing our library in this way it will actually go ahead and import the function from this file plug. GS because we have previously specified pass to this file inside the package Json of our package source code and now let's just add some random content inside the index.html of our client application I'm going to show a heading here and here we go we got expected result in our console so our function plug which was imported from our custom package has extracted usernames from the array of user objects so at the end let's just recall what we have done in order to implement this Library in our library project we have created file with the name index.js where we have implemented our function plug and then by specifying object under the key lip inside vid configuration we have told VD that this project should be built as an npm package instead of a client application and here under the entry key we have pointed to the file which contains the source code of our library and we will also use the couple more keys to assign name to this Library as well as the file name that should be used for bundle JavaScript file after the build then inside package Json file we have added some extra configurations to specify which files should be imported in case our users are going to import our library by using standard easp modules or by using function require and then just to be able to use this library inside a client application without actually publishing this library to the npm registry we have made this Library globally available by running npm Link in the rout of this project and then inside the road of our client application we ran npm link and the library name then we head to add to node modules folder and this command has created the special link inside node modules folder of the client application with the same name as our package name plug and this link points directly to the source code of our package which eventually allowed us to import this library from our applications JavaScript code and these are the basics of developing JavaScript packages by using V in the upcoming lessons we're going to learn about this whole process even more so in the previous lesson we have developed the package by using V Library mode and then included that package in here in our client application and that time we had only one entry point in our package but what if we'd like to create such package that would expose more than one entry point and what I mean by that is this that we could basically import some functionality like this from the sub pass so in this lesson let's figure out how this can be done firstly let's recall what functionality our package exposes so in the index.js file of our package we have only one function plug and then to be able to import this function from the client applications we had to modify package Json file and in here we had to specify a key called module where we have basically provided the pass to our main library file with that function and then in our client application it would basically let us Import in functionality from our package by using its name like so so now we're going to create another file which will also export some functionality so in our package let's create new file called log. JS which is also inside the source folder and here for demonstration we're also going to create only one function called loog which is basically going to be a wrapper around console lock method we're not going to complicate things too much because our main job here is to configure it in such a way so it can support multiple entry points of our package so next we're going to add configuration to vid config JS file to generate two different bundles for every Javascript file of our package so that later we could import function loog from the subp pass in the client application like this so before going back to our package project let's just use this function login here to print out array of users later we're going to need this to test our package and now back to our package project let's go inside V.C config.js and here we're going to tell vit about all our entry points of our package so basically instead of specifying in here only one p we will convert this to array which will contain all references to all files that we're going to expose in our package so I'm going to add another rering here and reference that new file called log. JS so this way we have told bit about all our entry points and now let's see what will be generated when we run npm run build so basically when we'll try to build our package and as we can see VD has generated four files so two files for every entry point because in order to provide support for importing our package as a commonjs module by using functional require it generates separate bundles and that is why we have four JavaScript files here instead of two but they all have the same name so how can we customize the name and thankfully that option file name inside configuration file also can accept closure and this closure takes two parameters first one is format that we are generating bundle for either ecmascript 6 or commonjs module and the second parameter here is the source Javascript file name which is in our case all JavaScript files are contained within Source folder so the name parameter will be either index or lock and here I'm going to use basic condition and check if VD is currently generating bundle for EAS create module we're going to use the following format for the file name and if it is currently generating bundle for command JS module besides using name as a file name we're also going to use custom extension for this file specified inside format parameter and this way we have customized names that we is going to produce while generating our bundles let's see what those names are one more time let's generate our bundles by executing npm run build and this time we still see four files but all of these files now have more appropriate names and again all these files have been generated inside the disc folder of our package project so now back to file package.json and in here in order to provide the way for importing our sub module by client applications we also need to add an entry for our second entry point inside this expert object so let's add another object and use the key lock this will be a key what client applications will use when they are going to import our subm module lock just like we have already used in the main doj of our client application in this import and also since we have modified the names which we produces while generating bundles we also need to correct these names inside package.json so firstly let's replace plug word with index in all these file names and then one by one let's correct a pass so it points to the correct file from the dist folder otherwise important things from our package is not going to work and now it's time to check if we will be able to import functionality from the subm module of our package so instead of publishing our package to npm registry we have used one trick by running command npm link inside the project of our package in order to make this package available globally in the operating system and in addition to that to add a link to this package into node modules folder of the client application we had to execute npm link but with package name inside the rout of our client application and this way this commment will add link to our package inside node modules folder and finally let's get back to testing and run development server inside our client application so that we could test if we would be able to import functionality from this subm module loog and then use this imported function to print out list of users in Here and Now switch over to the browser and as we can see we have two logs here first of which is produced by our custom function log that comes from our package so importing functionality from the second entry point of our package worked fine and we could even remove this log statement and instead print out result of the function plug by using our custom loog function everything is working fine so in this lesson we have reviewed how to build our library in case it has more than one entry point and as we can see it makes this process very simple let's continue in the next lesson all right so far we have created the library with multiple entry points and then in our client application we have imported the functionality from those two entry points right here from the main entry point plug and from subm module loog and just as a reminder the way we have organized the code in our library is as follows so in here we have a couple of JavaScript files inside source folder where each of those files contain only one function and then to tell node.js which modules have to be imported whenever client application will import functionality from our library by using either main entry point or sub entry point which in our case is called lock we have provided the pass in here for every buildt file which corresponds to every entry point of our library weather client side application is going to use native ECP modules to import functionality from our package or commonjs modules in both of these cases imports from our library are going to work fine but so far we have only tested importing functionality from our library by using naasri modules and in this case note while importing these modules looks into key import of the package Json file of our library in order to find the file which it should import and of course each of these PS specified in this package Jon file points to build files of our library that it has generated during the build process and it placed all these build files inside this folder by default so now let's see if it is going to work if in our client application instead of using native es6 inerts we're going to use commonjs synex by using function require so I'm going to convert both of these UTS to use function require like this and now this I'm doing inside of the main Javascript file of our main client application which Imports functionality from the library and now instead of checking result in the browser we're going to run this script main.js by using node so in the terminal I'm going to run node and the F name and as we can see we got an error saying that require is not defined in yes module scope and in order to fix this issue we have to rename an extension of this script on CJs so that nodejs will treat this module as common G s module but we're going to do it a bit differently and instead of renaming the current file I'm going to make a copy of this file with an extension of CJs like so and then let's just revert all the changes we have previously made to the main DJs file and leave file with an extension CJs as is which still uses syntax of commonjs modules with require function calls and now again let's execute main. CJs script in the node environment and in this case as we can see everything worked fine we got a result and as a reminder this script just extracts usern names from the array of user objects and then it prints out the new array which consists only of usern names so that's what we are seeing in here so as we can see it is possible to use our library in both cases whenever client application uses native ecmascript import syntax or syntax of common GS modules by using function required to import functionality from the library and this is possible because it while building our library has generated two versions of our library the one which is intended to be used with Native ecmascript Imports and another one for importing functionality by using common GS syntax in other words by using function require and of course if I'm going to go back to the source code of our library and in here I'm going to remove versions of of CJs builds those are the files responsible for providing support to import our library as command JS modules then after removal both of these files from the dist folder index. CJs and log. CJs if we'll try to execute our main. CJs script from the client application which still uses command GS syntax to import modules from our library in this case we're going to get the following error well obviously because we have just removed those files that were previously providing support to import functionality from our package by using commonjs syntax so as we can see it's very good that while building our library vit generates two sets of the build files the first set of files is intended to be imported as normal ecmascript modules and the second set of file provides support whenever users are going to import functionality from our Library by using require function so let's continue reviewing possibilities of building libraries with it in the next lesson so by now we have already created npm package and use this package in the client application let's start development server by running npm randev to start our application in the browser and the result of using our custom package is shown in a console it basically have extracted usern names from the initial array of the user object s and all of that has been implemented in previous lessons so let's just recall how that works in the main script of our Clan application we are importing functionality from our package but not only from the main module of our package also from the sub module lock and currently the project which contains our package has two JavaScript files index.js and lock. JS and each of these files experts one function and these two functions we are actually importing in our client application from different sub modules but as we can see currently our package is pretty simple it doesn't even use any third party libraries so in this lesson we're going to review how to integrate third party library in our custom package so in this file index.js we're going to import third party Library called collect. JS which basically has lots of utilities to work with array of objects and we're going to to leverage this function inside of our plug function but firstly let's just rename this function on plug and lock and then we'll basically do the same which is extract a key from each object of the collection but this time we're going to use plug method on our collection and we'll basically do the same here but by using method PL which Library collect JS provides us with like so and then besides returning this result we're also going to look the result in this function and right after we return this result so besides the main purpose of this function we're also loging the result in the console right away and then let's see what is going to happen if we'll try to build this Library so in the terminal let's run npm run buildt and we are receiving the following error that the collect JS Library cannot be imported since this Library does not exist in our package so what we need to to do is to actually install this Library by running npm install collect. JS and now once I'm going to start the build process once again this time it worked we still see four build files but this time we can notice that the sizes of some files drastically increased for example the size of the main file index.js is now almost 60 kiloby and that is because when we were importing Library collect JS in in our script VD has actually taken the whole source code of sord party library and put it in the build and which is why the resulting file of our library has much bigger size now but before we'll solve this problem let's just import our new function plug and lock in the client application and see if it's going to work so now we don't need to additionally Call the lock function in order to print results in a console because the new function plug and lock is going to extract keys from every object of the array as well as print the result in a console and in the console as we can see we are seeing expected result with the difference that our result is contained within items property of the wrapper object that's how the library collect JS works it returns us not only the result in Array but an object which wraps our collection but this is not the most optimal solution of building our libraries because anytime we're going to third party Library the file size of our library will be drastically increased so let's see what we can do about it and what it has to offer in this regard so moving on let's open up configuration file vi. config.js and in here we're going to add another option which is called rollup options which will be an object with the key external and this is where we have to specify Library names which we don't need to be bundled along with the code of our library and since by now we're using only one third party Library called collect JS I'm going to include only one name in this array like so and then let's watch the size of the bundlet file index.js so currently the size of index.js file is around 60 kiloby but after I rerun the build process by executing npm run build this time we see that the file size was drastically dropped and if we're going to take a look at the content of the build file index.js we're seeing only our cod in here and the import of the library collect JS but the source code of this library is absent and which is why we don't even need to install the library collect JS in our project so let's remove this dependency by running npm uninstall and dependency name and let's just rerun the build process of our package once again by executing npm run build so now if we go to the browser and check the result in our client application again we're supposed to get an error since our package relies on the third party Library collect JS but that library was not included in the build version of our package but surprisingly as we can see we didn't receive any errors so it worked and the reason it worked is that previously when we started development server vit has gone ahead and cached some dependencies in the folder. vit which is inside of node modules and this folder has cached version of the library collect GS so let's just go back to the editor open up no modules folder of our client application and remove that folder with sketched dependency is called vit so now let's restart development server in the client application and we are receiving an error that dependency client JS cannot be imported since it is missing from our client application as well as from the build file of our library and the first thing that comes to mind is actually install this Library into our client application so let's do just that I'm going to execute npm install and specify Library name collect. JS and then after running npm run Dev again we're receiving a different error similar but this time it could not resolve UTS of our own package plug because the link to our package which we have previously added to the node modules folder of the client application by executing npm link is gone for some reason so let's just add the link to our package inside node modules folder One More Time by running npm link and our package name I am not going to explain in detail what this common is doing since we were talking about it in one of the previous lessons so now that we have added back link plug which points to our package inside non modules folder we can try to start development server once again and again the previous error is back that it cannot resolve dependency collect JS so we're going to solve this problem in the next lesson when we will publish our package to the npm registry and then instead of using npm link to make our package available to the client application we're going to install our package as any other third party dependency by running npm install it's finally time to actually go ahead and publish our package into npm registry and as a reminder we are already importing functionality from our package in the main.js file of our client application and the way we made it possible is by linking our local folder with a package to node modulus folder of our client application by running the following command npm link and the name of the package would' like to link to our client application and then as we can see inside node modules folder we have the new link called PLU which points directly to the folder with our library and now instead of linking our local library we're actually going to go ahead and publish our package to npm registry so first of all what we have to do is to login let's run npm login in the rout of our library and we will be presented with a couple of prompts here we need to type in the username as well as the password that we have used to register on the npm website and yes I note we need to be registered up front in order to log to npm then we also have to enter our email address and right after we will receive the code on our email so let's enter this code in here and as soon as we're going to see this message that means we were successfully authenticated so I'll switch over to my browser and right here as we can see I don't have any libraries in my npm account yet so let's start the process of publishing our library to npm first of all let's go and open up file package Json of our library and here the first thing that I'm going to do is rename the value stored under the key name besides the name of our library I'm also going to use Nam space this Nam space should match username of the loged in user and what this will do is it will basically make sure that we are not going to get any naming collisions because there is a high chance that the package with the name plugged already exists on NP pm and now in the terminal to publish the package we have to run npm publish this time we get an error saying that our library is considered to be private and the reason is that in the package Json file we have the key private with the Val through so let's remove this key run npm publish again and it looks like publishing private packages is actually paid feature so when running npm publish we have to specify one flag called access with access modifier in this case I'm going to use public so this way our library will be publicly visible and finally the common has finished with no errors and if I'll switch over to the browser in here I can see that my library was published next let's go back to the editor inside the client application let's open up package.json and here let's remove the only dependency collect JS we're also going to remove the folder with this dependency from node modules folder as well as special folder. vit that generates to store cached dependencies and now in order to install the library I have just published we can use npm install and the full Library name the full name is stored in here under the name key of the package Json of our library project so let's see what is going to happen when we run npm install and our library name as we can see the library was successfully installed and now I can run development server by running npm Rand Dev and here I see the following error saying that some of the dependencies were not resolved and those dependencies are from our library and the reason is that currently our client application inside main.js file references old pass to import functionality from our library so we have to properly update this import pass by specifying full Library name in here next let's start development server again this time we got a new error and to understand what's going on in here let's open up the folder with our package inside node modulus folder of our client application and here we can see that there is no folder dist with the built assets of our library but in fact inside the package.json file we are referencing these files from the this folder cuz those are the files that have to be imported when users are going to import functionality from our library so we actually have to do one more thing before publishing our package to npm let's go back to the package Json file of our library and in here we have to specify the key files where we can list all the files and folders that have to be published in our case we only need to publish folder with the build up assets which is dist so I'm going to specify one folder name in here and then once we do any change to our library I'm also going to have to republish this library but with a different version number we could update this version manually or we could use npm command called npm version so we also have to specify which version number we'd like to update either the first one second one or the third one in this case it's not really important which one we're going to update so I'm going to update the third one and the word responsible for updating the third number is patch let's run this commment as we can see our version number was updated and also this number was updated inside package Json and to grab the new version of this library in the client application we have to reinstall it and before installing the new version of this library in the client application let's go inside node modules folder of our client application and manually remove the folder of our library from here and right after that we are ready to install a new version let's run npm install and our library name and now we will take a look at the content of the library inside non modules folder we can see here that this time only one folder is present which is this this is that folder we have previously specified under the key files inside package Json of the library and which is why only this folder has been published to npm let's run development server once again and this time we also got an error but the error message is different so it cannot install the library collect GS but in fact we reference this library from the source code of our package right here inside index. GS but in fact we have not install this library in the client application as well as in our package so this dependency is not nowhere to be found and the reason why this library was not included in the buildt file of our library is because inside v. config.js we have manually specified that we should not include this external dependency into final build of our library so to fix this issue we have to go inside of package Json of our library and in here let's specify one more key called Pure dependencies and these are the dependencies that our Library depends on but it doesn't include those dependencies so actually client applications will be the ones who will be responsible to install this library in order to use our package so let's specify here one perer dependency collect. JS this way we are saying that our library depends on this third party library and then of course I'm going to have to republish our new version of the package let's firstly update the version of our package by running running the corresponding command and then let's go back inside the folder with our client application let's remove our previous version of the library from node modules folder and reinstall it by running nbm install so what actually happened this time is this besides installing our library we can see that inside node modules folder there is collect JS folder which means dependency collect JS was automatically installed along with our package and the reason it was installed automatically is because we have previously specified this dependency under pure dependencies key inside of our library so from now on when any client application is going to install our library the dependency collect. JS will be automatically installed and finally if we're going to run development server inside of our client application eventually it worked and in the browser we can see an expected result in a console and also so let's see if production build is also going to work I'm going to run npm run build to build this client application the build has finished without errors so that's good and now let's run this build in the browser by running npm run preview and then by opening up this URL we see the same result as in development mode so we were able to successfully publish our package to npm registry and additionally our package contains external dependency collect JS which is not bundled with our library so all client applications that are going to use our library once they're going to install our library all third party libraries which our library depends upon which in this case is only one dependency collect GS they are going to be automatically installed so that's about it for this lesson let's continue learning with in the next one in this lesson let's review how we can optimize images by using VD and for that I already prepared default vid project let's open it up in the browser and start so at the beginning as always let's just do a little preparation let's switch over to index.html file and here I'm going to add an image and in order for this image to not exceed the available wids of the browser let's assign wids 100% And then what we're going to do inside main.js firstly let's clear everything from here an import an example image which I'm going to add in this project in a bit so then once we got the pass to this image inside the image variable let's just select Dom element of that image we have just added and assign the pass of the image to the source attribute like so let me just quickly add an image to this project here it is this is how our image we're going to optimize looks like and then in order to easily see the size of any file within vs code we can use the following extension I already have this installed and the way this extension works is it just shows the size of an active file in the status bar at the bottom right corner I currently have my status bar hidden so let me just enable it and right here I can see the original size of this image as we can see this image is quite big and the size exceeds 1 MB and now before proceeding further let's switch over to the browser and make sure that this image shows up and everything looks good we can continue so in order to optimize images VD has several plugins and one of them we're going to use in this lesson I'm going to use plugin called VD plugin image Optimizer so this plugin relies on two other libraries sharp JS and SVG o for image optimizations so first things first let's just install this plugin by running the following npm code command I'm going to copy over this command and run it in my terminal and then since this plugin relies onto other libraries those libraries have to be manually installed so one by one I'm going to copy these commments to install these two libraries firstly let's install sharp and right after that let's also install another Library SVG o and once the installation process is finished we have to configure this plugin and the way we do this is by inserting this configuration into our re configuration file currently I do not have this file so let me create it and paste in here all that configuration there is nothing special about this configuration and the most important thing here is that we import and include our new image optimization plugin and add it to the vid pipeline actually this plugin allows us to configure a lot of things but we're not going to review any possible configuration option and instead let's just see how to optimize an image with an extension. gpg so let me copy over this configuration option and paste it into my V.C config.js and by using this option quality we can configure how much we want all gpg images to be optimized so as an example let's specify 80 and by the way image optimization only happens when building the project for production so I'm going to have to run the build by using npm run build and right here we can see the new output this is the result of that image optimization plugin and right away we can see in here that two images were optimized the first image is that image we just added to the project and another one vid SVG is the default one which recites inside public folder by default so as we can see the size of the first image was reduced by around 300 kilobytes and now to see the result in the browser I'm going to have to run npm run preview to open up build project in the browser and by following the address Local Host 4173 we can see in the browser build project and there we go we got here an optimized image but the size here is a little bit different than the one we have just seen in the terminal anyway our image optimization is worked so now let's just change the value of the quality configuration option for example let's specify 40 and then run the build by running npm run build and this time the image size was reduced even more and of course if I open up this build in a browser we can see in here the newly optimized image with the size of 392 kiloby so let's review in the editor let's open up original image with the name image. gpg and as we can see the original size of this image was over 1 MB but then when building the project for production the size of this image was dropped to 34 4 kiloby and actually the point of this lesson was not to show you how the particular plugin works but how to include any plugin into it because the installation process as well as configuration will be pretty similar and of course there is not the only plugin which allows it to optimize images there are also other choices so we just have to pick that plugin which satisfies our needs and then follow simple steps to install and configure this plugin and then we'll be good to go let's keep exploring capabilities of itd in the next lesson in this lesson let's explore how we can create our own vid plugins so I have already created default vid project let's run development server and just to make things a little bit easier while developing our plugin let's use another plugin called VD plugin inspect and what this plugin will allow us to do is it will provide us with such inspector view where we can see all the Transformations that are going to be applied to our modules by all plugins including our own so let's quickly install this plugin by using npm and run this commment in the terminal and then let's copy over this code to include this plugin let's create configuration file with config JS and paste in here that code and now I'll have to restart my development server by running npm randev and in here besides our up URL we can also see inspector URL and by opening up this URL in the browser we can access our inspector so if we see this page that means our inspector was installed successfully we can continue so we're going to create our own plugin which is going to allow us to import CSV modules and to transform CSV code into valid JavaScript arrays we're going to use nodejs Library called node CSV and since this library has several libraries in it the one that we need is called CSV pars so let's install inst this Library by running the following npm commment in our terminal and then before actually getting to writing our plugin let's do a little preparation by adding an empty pre Tech in our HTML file and then let's switch over to main.js and remove everything from here we're going to start from scratch so what we're going to do in here is try to import the CSV file we're going to create soon and then all the content of the CSV file we're going to assign to that prech specifically to text content property like so but since products will be the array firstly we have to stringify this array and which is why we're calling message stringified to turn this array into a string and of course this statement should import CSV file so let's change this extension on dot CSV and then we'll add this products. CSV file in the road of this project and here I'm going to insert some random data we're going to work with products and their quantities the first line will contain names of The Columns of the CSV file and all other lines will contain the data for every column like so and of course by default VD does not support important in CSV modules so when we switch over to the browser we'll actually get an error because as soon as our browser tries to make a request to products. CSV file our server responds with the row content of the CSV file which is not the valid module hence this import didn't work so before actually importing CSV modules we have to apply custom transformation which would transform CSV code into valid JavaScript array so it can be imported as other ecmascript modules so our transform JavaScript array could be assigned to the products variable in here and now we're going to get to the main part of this lesson which is creating the vid plugin so theid plugin is basically an object which we should add to plugins array in our vid configuration file so in here let's create a new object firstly we'll have to specify the name for our plugin I'm going to use V column CSV and then most importantly we have to provide a special function cook called transform which in our case will be a synchronous and this function will be called automatically by it whenever we're going to import any modules inside JavaScript files the first parameter of this hook will be the content of the imported module and the second parameter will be the pass to this module I'm going to call these parameters source and ID so once we have fetched the content of the CSV module we need to transform this CSV code into JavaScript array which we can do by using function called pars and this functions going going to be imported from that CSV pars module that we have installed at the beginning of this lesson also to this function I'm going to pass configuration object with only one option columns that will tell this parse function that our CSV code contains name of columns as the first line in our CSV file so it can properly transform our CSV code and then let's go up and in here add an import for the pars function from the CSV dasp pars package and the sync subm module like so and then by following conventions of it the transform function has to return an object which should have a key called code and in here we have to provide valid script code which is supposed to be exported when people are going to import CSV modules in JavaScript files and now very important thing to note is that this hook transform is going to be called anytime we're going to import any module inside JavaScript files not only CSV files so we actually have to restrict execution of this hook to only CSV modules and we can do this by adding conditional and wrapping All The Code by this conditional so here we're going to use regular expression and check if the currently imported module is indeed CSV module only then we're going to run this transformation otherwise our again is not going to do anything when importing other modules so just for clarity let's also print some variable values in here for example Source ID as well as records and then in the browser we can see the result of our plugin so there is no error anymore while importing CSV modules and what we got instead is actually transformed CSV code into JavaScript array on the page let's just make this output a little bit prettier by adding style white space with the value of PRP to place the content on multiple lines and if we select the request which was supposed to fetch CSV module from the server in the response we can see that the response was turned into validas module which exports an array of objects and apparently it contains objects for every line from the CSV file and then this variable was stringified and assigned to text contain property of the preag which is why we're seeing this array in the stringified form on the page and now in a server console let's see the result of these variables so if I refresh the page these variables are supposed to be printed in the server console and there we go so this value corresponds to the variable source which contains all content from the CSV file and the other output which is the pass to the CSV file corresponds to an ad variable and finally after executing this whole thing we got the transformed CSV into constant called records which was later transformed into volid Mas script module string and this is actually the result of outputting that variable in the server console so one more time while importing CSV module in our Javascript file we got transformed CSV code into JavaScript array and this JavaScript array was assigned to the products variable which later was stringified and assigned to text content property of the prech and now let's take a look at the transformation of our custom plugin that was applied to CSV module so let's open up an inspector click on our module products. CSV and right here we see the following transformation which corresponds to the name of our plugin with colon CSV so our plugin has read the content of the CSV file and transformed this code into validas script module and that's about it we have successfully implemented our custom VI plugin which allows us to import CSV modules in JavaScript files link to the source code will be in the video description in the previous lesson we have implemented the plugin which allows us to import CSV files inside of ecmascript modules and the way it works is as follows whenever we import CSV file the CSV synex gets transformed into JavaScript array of objects but currently our plugin is kind of inlined inside of vid configuration but usually plugins are extracted into separate JavaScript modules in the form of factory function so let's try to move it into a separate file just like it is done for the inspect plugin here we're just importing this plugin and then coling it inside this plugins array so we're going to do the same with our CSV plugin let's just cut this whole object create a new file for this plug-in in the road of our project let's call it vid plugin CSV and this module is going to export one function which will be a factory function for our plugin here we're going to paste that whole object with plug-in definition let's also move that import that we need in this plugin of the function parse and since this function parse gets imported from the sync subm module the there's no need to make our transform hook a synchronous so we can remove this as in keyword from here let's also rename this plugin on simply CSV and then let's get back to our vid configuration and include this plugin by firstly importing Factory function from V plugin CSV file and then just like it is done for inspect plugin right next St we're going to call our Factory function CSV and this way we have just included our own plugin and please note that there is no difference between including plugins in line in the form of JavaScript objects or by moving them into Factory functions and then calling those functions right here in this plugins array so just to make sure that our plugin works as expected and we got the same result as before let's run development server and take a look in the browser as we can see we get the same data that means our plugin works as before and now a couple of words about existing plugins that exist in V ecosystem so first of all there is a list of official plugins provided on the official documentation page right here and then since V internally uses another bundle called rup to build projects for production there are a bunch of RAB plugins that are compatible with VD projects and the list of RAB plugins compatible with v projects can be found on this page and of course besides official r LA and with plugins there are countless of plugins built by the community for example there is ASMR app repository which has collection of resources specifically for rup and this page also includes list of community plugins and similar page also exists for V this repo is called awesome vit here we also can find a bunch of links to everything related to V projects as well as plugins developed by the community now let's go back to our plugin configuration and consider a couple more options that we can use for our plugin so an important option is called apply and this option allows us to specify which environment our plugin should be included into for example if we'd like to use this plugin only during development we can specify Val serve for this option and this way plugin will only be activated while we are running development server and by using another keyword called build allow us to include this plugin only in production builds in other words when we are running commment and PM run build to build the project for production so let's see for example I'm going to specify value serve which means the plugin should be included only in development mode and then if I run production build by running npm run build right away I get an error because our plugin which lets us import CSV modules was not actually included in the production environment and then if I'll go ahead and change this value unbuilt then while running development server by execu an npm run Devo in the browser we're going to get the following error since our import of the CSV file didn't work and besides specifying predefined vales for this Supply option we can also specify a closure which gives us morine grain control disclosure accepts couple of parameters first of which will be conf configuration object and another parameter will also be an object with a couple of useful properties such as comment and mode and then let's just print out each of those variables to see what they contain and by looking in the console we can see that the first parameter basically printed the whole configuration object command variable stores Val serve and mode variable stores Val development since currently we are running it in the development mode and based on this Val we can do an extra checks and if we're going to return value through from disclosure that means the plug-in should be included so for example if I'd like to include this plugin only during development I'm going to compare variable mode with the development word and this way this plugin will be included only while running development server and of course if I'll go ahead and try to build a project for production I'm going to get the corresponding error saying that CSV module cannot be imported since there is no plugin which recognizes such Imports also there may be a situations where we need to access configuration object in other hooks for example in this transform hook so how do we get access to this configuration object from other Hooks and there is actually another hook that we provides as way called config resolved this hook will be called automatically before transform hook and it receiv gives configuration object which we then can store in a variable so it will be accessible to other hooks so I'm going to declare here variable called config before returning configuration for this plugin and then inside config resolved hook I'm going to assign resolved configuration object to this varable config so then it's accessible from other Hooks and then based on configuration values we can easily do extra checks in this transform hook for example let's compare value serve with the value stored in common variable and based on that we're going to specify this value as the value for option columns for the parse function so now let's take a look at the difference firstly let's run our development server and check the result how our CSV code was transformed as we can see we got an array of objects where every key corresponds to the field from the CSV file and every such object corresponds to individual line from the CSV file and for example if I'm going to run development build in this case we're supposed to get different result so let's just run this production build in the browser by running preview server and as we can see the output is different in this case the first element of this array is another array which consist only of column values from the CSV file and all other elements store vales from Individual rows or the CSV file and now let's review one more useful hook which basically allows us to transform HTML content and this Hook is called transform index HTML which is about to receive the whole content of the HTML file so in here we can do all necessary transformation with the content of HTML file so let's replace the closing body Tech with the following I'm going to put basic script at the end of the body element which will open up a dialogue with the word hello like so and it is very important to position all the hooks on the same level so the transform hook as well as transform index HTML hook should be included on the the same level like this so now after running the development server in the browser we can see that firstly we got an alert with the word hello so our transformation of the HTML file was successful and at the end of the body element we got that script which opens up the dialog so in this lesson we have only reviewed a couple of hooks that we can leverage in our plugins but in fact there are a lot more of such Hooks and documentation about those can be found in the offal vid documentation but even only using these hooks we get a lot of flexibility and we can transform imported modules in whatever way we like let's continue learning about VD in the next lesson let's consider several options which allows us to configure development server so when we start development server by running npm randev it starts with using Port 5173 but then if we're going to go ahead and run another copy of this server the port will be changed dynamically because the previous Port 5173 was already taken by the previous copy of the development server and of course this port is configurable and just like other configurations we can override the port in vid configuration file so let's create an empty vid configuration file and in here we're going to specify an object under the server key where we can configure several aspects of the V development server so for example I want the port to be 33 33 and now after running npm randale we can notice that the port we just specified was used for development server but still if we're going to launch another copy of the server the port will be changed and this is a pretty convenient behavor but in case we'd like this commment to throw an error if the specified Port was already taken we can specify another configuration option called restrict port with the Val true and now if we're going to launch one instance of the development server and then we'll try to launch another instance in this case instead of picking up Port which is available it will throw an error CU part 3333 is already in use another option called headers allows us to specify custom headers for we responses as an example let's specify one header with a name a and the value B and then in the browser if we'll inspect the request for fetching the current page in here under the response headers we are noticing our custom header a and this header will be added not only in the response for fetching the current page but also for fetching other assets such as JavaScript files another interesting option is called proxy and what this will allow us to do is to provide custom URLs which will be accessible from our Dev server for example I want to use URL SL products to fetch list of dummy products during development and we can achieve this by specifying custom option proxy this option holds an object where keys are addresses that would like to be accessible and the values for those keys will be addresses that do it is going to redirect those requests so for this particular example I'm going to use third party servers called dami Json which provides us with dami API it basically gives us set of dumy end points which we can use during our local development so in this case I have used the first end point products and now while accessing this endpoint products from our local Dev server I'm supposed to get list of fetched products received from damage Json API that's exactly what we're seeing but also besides specifying only addresses for keys inside a proxy object we can also provide more detail configuration in the form of object so for example I want to have an API Road in my development server which is going to redirect me to that same damage Json service but while r correcting me to these servers I don't want to include API segment in the address so I'm basically going to modify the final URL which is going to be used to make a request to damage is on API by completely removing API segment from the URL like so and this configuration is going to allow me to do the following type of requests for example if I'm going to refer to /i/ products since a API segment will be removed the result in url will be as follows so only products segment will be added to the end of the D jon.com domain so now let's try to call this URL in the browser /i/ products this time I'm receiving an error with an error code of 500 this error has something to do with different Origins so without getting too far of the topic the documentation suggests us to use another option chain origin with the Val through to avoid errors related to different Origins so now if I'm going to make that same request on API SL products I'm receiving the list of products but this time we can do even more for example let's use different URL let's try to fetch list of posts by using post URL and to do this I simply have to change the segment on posts like so as we can see it has worked and we got list of posts in the response so for now we were only specifying all configurations for the server under the server key in the configuration file but we can also assign separate configurations for the preview server so let's build this project for production by running npm run build and then run preview server by executing npm run preview as we can see the default part of the preview server is 4173 let's just try to overwrite some configurations for the view server for that I'm going to copy over this object paste it down here and rename option server on preview and this configuration will only be applicable for the preview server let's change something in this configuration for example let's use different port remove this headers object and add another option called open here we can specify which address should be open in a browser by default after starting preview server I'm going to specify our custom URL API SL products and just because we have previously configured proxy a request was made to the following URL API products and we got the list of products on the page and this is how we can override configurations for the preview server as well as for the development server in fact there are many more configurations for configuring servers and all of them are described in details in the official withd documentation in one of the previous lessons we have implemented the custom withd plugin which allows us to import CSV files inside JavaScript modules inside of our main Javascript file we are importing the file products. CSV and then rough content of the CSV file will be transformed by our plugin and turned into array of JavaScript objects and from the code point of view it looks like this inside of the configuration file where in including this plugin by calling Factory function CSV which we are importing from V plugin CSV file let's open up this file and take a look at the implementation so here we're basically using the hook called transform which will be called by we any time we are going to import CSV files in easr modules and then we're basically converting the row content of the CSV file into valid JavaScript array of objects by using this function pars and at the end we are returning valid easr module to the client which contains the data from the CSV file in the form of array of JavaScript objects and here is how our products. CSV file currently looks like that we are importing in our main Javascript file right here and then we're basically injecting the content that we have received after importing that CSV file into the prech and which is why we're seeing the content of the CSV file on this page but the the thing is that now if we're going to update the content of the CSV file it will cause the full page refresh of the browser and just to see it in action let's create arbitrary constant plugin and see if this plug-in constant will still be available after we're going to modify CSV file let's just go ahead and make any modification to the content of the products. CSV file I'm basically going to add another row in here and then in the browser let's see if the plugin constant is still available so first of all we're seeing here that the new line that was added in the CSV file was appeared on this page but the plugin constant is undefined because browser has made full page refresh in order to update the content on the page so now we're going to implement support of so-called hot module replacement for our plug-in and this technique basically allows us to update modules that are modified F without doing the full page refresh in the browser it's called HMR which stands for hot module replacement and in order to implement hot module replacement for our plugin we need to use another hook provided by vit called handle hot update this Hook is going to do a synchronous operation so let's mark this function as an as sync function and as a first parameter into this function V will'll pass context object so this function will be called anytime we're going to modify any module that we are currently importing in our JavaScript files but we don't need to listen for all updates but only for updates that happen to CSV files so let's use the same condition we have used in the transform hook and check if modification has been done to CSV file only then we're going to run this logic inside this if conditional but here in order to to access the file name which was updated we need to reference property file on this context object and the way we're going to implement hot module replacement is by leveraging websocket connection and firing custom event to the client by using method send on the websocket object like this and then we also have to specify custom configuration for this event let's specify the type which will be a custom the event name Will will be CSV D update here we can use any kind of name we like later we're going to listen to this event in the client code and then we also have to specify the data key and this key will basically store the content which we're going to send to the client for now let's just read the content of the updated CSV file by calling method read on the context object and since this mthod isn't synchronous we have to await the response and then then assign it to the data property like so and right after that just to tell it that we are going to take care about hot module replacement ourselves we need to notify Vi about it by simply returning an empty array from this method like this so now let's try it out one more time and check if the constant that we're going to declare in here will be available even after we're going to modify CSV file so I'm going to remove the last line of the CSV file and check if the plug-in constant is still available so as we can see it is still defined that means the browser hasn't reloaded the page but we also haven't seen any changes to the content on the page because we are currently not listening to the custom event that we are firing from the server so this was the first part of implementing the hot module replacement which is firing an event from the server to the client the next part is to actually listen for this event on the client side so I'm going to switch over to the client script and in here first of all let's check if the object which is responsible for hot module replacement exists this object is stored on The Meta property of an import object and if so we're going to register a listener for the custom event we have specified on the server with the name CSV update and as a second argument to this function we have to pass closure with one parameter and this parameter is basically going to store the data that we have specified under the data key while sending this event right here so first of all let's check it out what we're going to receive in this data parameter I'm going to printed out in a console let's switch over to the browser as we can see currently I have three products in my CSV file let's go there and change the content and after that in the browser we can see that the console shows new content of the CSV file including our latest product Edition so now we're going to get to updates on the actual page because after CSV file is modified we need to properly change the content on the page to do so in our client script I'm going to copy this line and paste it into this Handler so anytime we're going to receive the new content from the server we're going to update the content of the preag by assigning updated content but currently this content will be ped as a row content of the CSV file but what we need to do instead in our plugin is to actually transform CSV content into JavaScript array by calling function pars just like we have done in this transform hook so let's wrap the content of the CSV file in the pars function call and this way client application will receive JavaScript array instead of a row CSV content so now back to the browser and check it out once again initially I have four products in my CSV file let's remove the last product from here and see how it will be reflected in a browser as you can see content was changed and now instead of four products I have only three which corresponds to the latest content of the CSV file and that means that our hot module replacement worked and from the server y websocket connection we have received updated content of the CSV file in the form of array of objects and of course now as soon as I'm going to do any kind of modifications to the CSV file instantly I'm going to see those changes reflected on the page so as we can see our for product was back and now let's just do one little Improvement to our plugin by passing structured data to the client so I'm going to to send an object with two properties First Property will be a URL and second one data URL will store the pass to the module that was updated and the data will store the new transformed content of the updated module let's just add more descriptive message on the client side in the console and say which module was updated and here we have to destructure two properties URL and the data those are two properties we have just specified in the source code of our plugin right here so now let's check it out one more time in a browser we'll create constant plugin and if this constant will be available this will be a sign that the browser hasn't done full page refresh so after modifying the content of the products. CSV file we can see that it was reflected on the page as well as we can see the new loog which shows the pass to the file which was updated and of course the constant plugin is still available so our hot module replacement for CSV files works great and this is how we can Implement hot modu replacement in withd projects by basically using the function handle hot update in our plugin and then sending custom event via websocket to the client with appropriate payload and then on the client side we are registering The Listener for this when accept updated data and then do whatever we need with this updated data in order to apply hot module replacement update so this was one of the ways how we can Implement hot module replacement in vit now let's see how V allows us to establish client server communication just like in the previous lesson when we were using hook handle hot update to implement hot module replacement feature for our plugin and in here we were using webset up object to send events to the client and then we also had a chance to specify which data exactly should be sent along with this event and in our client script we have registered listener for this event accepted the data received from the server and then we were able to do anything we want with this data to implement hot module replacement but besides using this hook handle hot update which will be called only when any module that we are importing in JavaScript files will be changed we can use another hook which allows us to configure the server and this Hook is called configure server which accepts a server instance as the first parameter and by using this server object we can also access websocket connection so just like previously we can set up a listener for all kinds of events for example there is a default event called connection which will be fired whenever our webset connection will be established so we can try listening for this in here and once we establish web sucket connection let's send any1 to the client with the name connected and as a payload we can send simple message connection established and now to be able to listen for this event from the client code we have to register a listener by using object hot so here we also call a method called on and as a first parameter we have to specify event name with which will be listen in for and as the second parameter we specify the closure which will be our event handler so this closure is going to receive the payload sent from the server along with this event and now let's see what will be printed in a console I'm going to switch over to the browser and as we can see in here we have that message sent from the server once webset connection was established in this way we can exchange messages between server and the C L for example let's fire another event as a response to the server with a name pin and the payload which will also be a simple message hello server and now going back to our plugin implementation inside of this configure server hook let's register another listener for the pin event and specify an event handler this time event handler is going to receive two parameters first of which will be the payload sent from the client and the second parameter will be the client itself in other words the object that represents the connection and inside of this closure we will be able to use this object to send events to the client so as a response let's send event with a name pun and the message hello client and now one more time let's switch over to our client script and register a listener for this por by using that same object hot as an event handler let's specify the closure which will receive the payload as the first argument and print this payload in a console so now in the browser console we can see two messages the first one was printed once websocket connection was established because previously on the server site in our plugin implementation code we have registered listener for the connection event and as soon as webset connection was established we send the event called connected to the server with the message connection established and then client has received this event and printed that message in a console and now to reply back to the server client send another one with a name pin and the message hello server on the server side we have registered a listener for D pin and also printed the message which will come from the client in the server console so now if we're going to take a look on the server console we're going to see here that message received from the client hello server and finally besides printing this message in a console we're also firing another E pun to the client with the message hello client and in our client script we are basically listening for this event and printing received message in the browser console and which is why we're seeing in here a second look that says hello client received from the server and by the way all those listeners and EVS which we have used in here this code will be executed only if an object hot will be available because we have wrapped everything in the if conditional and the thing is that this object hot will be available only during development so if we're going to build this project for production by running npm run build this object hold will not be available so all this code will be basically removed from the production bundle by using Tre shaking so at the end let's just make sure that this is the case I'm going to print out simple message in here just to see that this code will be executed and indeed we're seeing that lock Hut in the browser console along with other locks because currently I'm running development server but once I'm going to switch over to the console and run the common to build this project for production and then run production built in the browser by executing npm run preview sure enough I'm not going to see any logs whatsoever this is because that conditional block which we're checking if object is present has not been executed since hot object is not available in the production build so this is how we can exchange messages between our plugins and the client code by using websocket connection provided by V in one of the previous lessons we have implemented hot module replacement for CSV modules the way we have done this is by using handle hot update hook inside of our plug-in implementation so in here whenever do c PV file will be modified we would fire Event Y websocket connection to the client and include all necessary data along with this event so that client could receive this data and then Implement all necessary updates and in this lesson we're going to see how we can Implement hot module replacement for JavaScript files so I'm going to comment out all these listeners we're not going to need them in this lesson and also we don't need to fire any custom events from our server so let's just comment out this hook configure server which was basically used to Fire custom V web soet connection to the client and before getting to implementing hot module replacement for JavaScript files let's do a little preparation I'm going to create new JavaScript module in the root of the project let's call this file module. JS and here let's add some dami code for example let's expert constant with a name message and the random string and also let's add one more expert which will be a default expert also with a random string and now we're going to use HMR API to implement hot module replacement and all the code which we will need for hot module replacement we're going to wrap in the if conditional and check if hot object is present then we're going to mement HMR so that b could properly remove this Cod when doing production builds since we don't need to provide HMR during production so in order to implement hot module replacement for this specific module we can leverage method called accept on the object hot so this method accepts closure which in turn accepts one parameter which will be updated content of this module let's call this parameter updated module and then print out this variable in the browser console and just to see it an action we of course have to go back to our main Javascript file and write an import statement to import our new module and regarding all other code we actually don't need any of that so let's comment everything out besides our import and one more thing before we'll check it in a browser let's go back back to module. JS and print something out so we can see that this module will be loaded and here we go we got that Lo that means that our module was properly included and now let's see what is going to happen as soon as I'm going to modify the file module. GS for example let's change this string and in the browser console I'm seeing a different loog which was just modified because after updating this file this module was executed again and then we also got this lock which contains updated content of this module in the form of an object so here we can see a default expert of this module as well as a named expert of the constant message and this log was printed by using disclosure that we have passed into accept message so now if I'm going to modify the value of the message constant for example right away I'm seeing the new log in the browser and this time the constant message contains the new value that we have just updated so anytime we're going to modify module. JS file we're going to see here new log with updated content of that file and by the way all this is happening without full page refreshes but what if I'm not going to use call accept in this module Let's test it out let's comment out this part in the browser I'm only seeing one lock which was printed on the initial page load but after I'm going to modify by the file module. JS in the console we can see only the new Lo without all previous outputs and that is because browser has made full page refresh so in this case there is no hot module replacement and again if I'm going to go back to the editor and comment this code back in then initially here I'm seeing only one loog from the module. GS and after I'm going to modify this lock we're still going to see the old lock as well as the new output and in addition to that we got an object which contains updated data of the module so in this case as I'm using accept method in my module anytime we're modifying module. JS browser is not going to make full page refresh in order to update this module in a browser because all these updates are happening by using hot module replacement technique and now let's consider another example so what if my module. Js is going to import another module let's emulate this situation let's create the new file and call it subm module. JS this module is going to have only one default expert of the random string and then we're going to import this module from within module. GS right here and now let's say we want to monitor changes in all those modules we are importing in this module so for example I want to run some code anytime the module sub module. JS will change so in here I'm going to use another code to Method accept which in this case will have a different shape as the first parameter we can provide an array which consists of all those UTS we like to monitor changes in so for example in here I'm going to watch file called submodule dogs so I'm going to include this name in here and then in this closure we are going to receive an updated content of every module that we are monitoring since in this case I'm monitoring only one module I'm going to destructure this parameter and extract only the content of this subm module file and eventually let's see what will be contained in this new subm module variable which is supposed to give us updated content of the subm module file and before checking it out in the browser I'm going to include conso statement inside sub module. GS for testing purposes so on the initial page load we can see two locks obtained from loading subm module. JS as well as module. JS and now let's see what is going to happen if I'm going to modify the content of the subm module. GS let's let's change this message go back to the browser and here I can see the log from subm module. JS again because after modifying this file it was executed in the browser one more time and then I'm seeing another look which contains updated content of the modified subm module. GS file and that is because in our parent module which is called module. GS we have registered this listener which monitors for changes inside subm module. JS file and when that change occurs it is going to print the updated data of this subm module in the form of an object and if I'm going to make mistake in the subm module name and then we'll do any modifications to this subm module then in a browser I'm still going to see the lock but this lock comes from a different place it is actually this part of code which prints that log entry so just to make it all clear let's comment out this part and modify subm module. JS once again and as we can see after modification there are no extra locks in a console because we are no longer listening for changes in the subm module so let's go back to module. JS and fix that mistake in this name subm module. JS and one more time if I'm going to go ahead and modify the file subm module. JS sure enough in the console we're going to see a new log entry with an updated content of the subm module file and by the way if we're going to make any syntax errors in our modules then dead log which is responsible for showing updated content of the module we'll print value undefined instead so if we're planning to use this value in our closure it's necessary to firstly check if theed value actually exists so we're going to R this part in the if conditional so now if we're going to make any syntax errors in our modules it will prevent us from potential crashes and it's actually good to do these kind of checks most of the times so let's add the same conditional to this closure let's keep learning it in the next lesson so by now we already know how we can accept HMR updates by using method accept and apply them to our page and this method accept has a few signatures first one allows us to accept updates of the module itself and the other signature allows us to accept updates from dependencies of this module in other words from those modules that are imported in this module like we're doing in here where we are monitoring changes inside of subm module. GS but there can be such situations where when modules are updated and updates are applied in a browser those updates might also leave some kind of side effects for example those updates might modify Dom structure or change some data in local storage of the browser or even a simple console loog statement can also be considered a side effect and sometimes before applying updates of the module in a browser before we need to run some kind of a code which would clean up those side effects left from previous executions of this module it might sound complicated but in fact it is really simple let's consider one example I'm going to create variable Styles and then let's declare the function at stylesheet which is basically going to add Styles into head element on the page so in here I'm going to use Dom API to create Dom element which corresponds to the style tag and then we're going to assign arbitrary styles to the inner HTML property for example let's make background color of the body Indigo and text color will be white and then all we have to do is to append this style element to the Head element like so by using method append child and of course to apply these changes we have to execute this function once current module will be loaded in the browser so let's call the function add Styles shet right here and also let's open up index.html and in here we'll add H1 element so in the browser we see that those styles were applied and if we take a look at the head element at the end we can see that style element that we have just added so far it looks good but what is going to happen if we're going to modify the Styles in any way for example let's change change the color on yellow and take a look in the browser the color was properly applied to the Page by using hot module replacement but in fact if we take a look at the Dum structure here we have two Style Elements so the previous style element was not removed and the new one was just added so the previous execution of this module has left side effect in the dome by adding style element but right after we have updated those Styles the previous style TCH was not removed So It produced so-called side effect but we didn't clean up that side effect before applying new updates and inserting new style element and as you may have guessed anytime we're going to do any kind of changes to our module we're going to get the new style element appended to head element so now let's see how we can actually clean up after ourselves and anytime we're going to modify this module the previous style tag will be removed and the new one will be appended and for that let's create new function call it remove style sheet and all this function is going to do is basically remove Styles Dom element by coling remove method like this but the question is where do we actually need to call this function remove style sheet and since this function has to be executed right before we're going to receive new HMR updates it provides us with another method called dispose that we also call on the H object and the closure which will be passed into this method should execute all necessary cleanup code to get rid of previous side effects so this is exactly the place where we can call our function remove style sheet to remove style Dom element so now before going back to the browser let's actually reset these Styles as they were initially let's also do a full page refresh to have only one style element on the page so now after I'm going to modify this module in the browser what we will actually see is that before appending updated Styles onto the page the previous style element was removed because that function remove stylesheet was executed inside of a closure of the method dispose which cleaned up our previous side effect before appending new element and just to see at what time those functions are executed let's just Place arbitrary console Lo statement into function add stylesheet as well as remove stylesheet so on the initial page load our module was executed and called function and style sheet and therefore new styles were applied to the page and after any subsequent modifications of this module we're going to see that before applying new updates our function remove styish sheet was executed thanks to that method dispose that we have called on the hot object so the previous styles were removed and then the new styles were added and this way we end up only with one style element on the page let's go back to the editor and remove these two console loog statements so by now we know how we can accept hot module updates by using method accept as well as how to remove any side effects before applying new updates by using function dispose and now a couple of words about standard vid events that we can listen to and there are several events that we can listen to and all of them are shown on this documentation page so for demonstration purposes let's just register listeners for some of these events as the first parameter we have to specify an event name I'm going to use before update event and as a second parameter we're passing the Handler which is going going to take some data received from the server let's just print out this data in the console and then duplicate this piece of code a couple more times to register listeners for other wins such as for after update and for the error reent like this and just to make it clear which conso Lo statement corresponds to which listener I'm going to add in here a label before update after update and error so again initially there are no looks that came from those listeners because none of those events were fired on the initial page load because they will be fired once we're going to modify the module so let's do just that I'm going to go ahead and change the color of the background and then in a browser we can see that firstly we have received the lock which came from the before update EV went listener with some metadata about the module which was updated when it was updated and the pass to this module so this log was printed to right before we have applied HMR update and the after update log was printed after we have applied HMR updates and this7 Handler also received the same object which describes the module which was updated and just to trigger the error went we have to make syntax error in this module and then in the console we're going to see that the error was printed which means the error handler was executed and the data that we have received in here contains the full description of the error and by the way the same error was displayed right here and this is how we can leverage those default events to be able to hook into HMR process and execute particular code at the different stages of HMR updates in this lesson we're going to take a look at how we can integrate framework view in vid project so I have already scaffold the default vid project so let's start development server by running npm randev and by the way whil scolding new VD project there is a special command that we can use which will basically scaffold VI project with view framework already integrated but just to better understand this whole process and to see what is going on under the hood we're going to do this manually and the first thing we need to do is of course install all necessary npm dependencies such as framework view itself and vid plugin which will allow us to convert files with an extension. view into Jo script code so after installing both of these dependencies we need to open up VD configuration file v. config.js and in here we have to include that plugin we have just installed plug plugin view into this array by calling this function View and then let's just remove everything from the main.js file and start writing view component so inside of our index.html file we already have an element with an IDE of up this will be an element where we're going to Mound our View application so firstly we're going to create the root component up. View and for demonstration purposes we we're going to use a very basic example of a counter component so I'm going to create here one reactive variable by running function ref this variable is going to store current value of our counter and inside the template of this component let's add H1 element with a text counter and right under we're going to add a button which will allow us to increment count variable so let's also output develop the count variable in here and register click listener on this button which will basically increment count variable like this so now that we have one view component we need to initialize View application in our main script so in here firstly let's import our root component from the file up. view and also we'll need to import function create up from The View package which is going to be used to initialize our review application and in here let's call this function create up pass in our root component and then call in function Mount and specifying an identifier of that element where we're going to mount our application into and just as a reminder we already have an element with an IDE of up in our index.html so now in the browser as we can see we have a working counter so our View application was properly initialized and now let's take a look at the transformation which wi has applied to our app component I have additionally installed plugin called VD plugin inspect in order to see what transformation VD applies to our modules so we can open up this URL in the browser and in here we're going to see all those Transformations done to our modules so whenever we are importing up. view component the plugin is going to take the content of this component and turn all this content into valid JavaScript code in other words into the render function which will be called on the client side and render our component on the page and now let's also take a look on the network tab so when browser fetches main.js then it fires the call to the server to fetch the content of the update view component but instead of giving us the r cont content of the update view component vit has applied the plugin to the file with this. view extension which would transform view template into valid JavaScript syntax and this is the code which is responsible for rendering counter component on the page so as you can see it was very easy to integrate view framework into vid project initially we just had to install to npm dependencies view framework itself and vid plugin to transform View files into JavaScript code and then we had to include this plugin inside of V configuration file just like any other we plugin and after doing all these steps we have actually provided the full support of the view framework inside vid project so we can develop View application in a normal way by creating components with view extensions importing those components they will be properly transformed into valid JavaScript code and and everything will be working fine and this is how we integrate view framework in vid projects in this lesson we're going to take a look at how we can integrate react into vid project so I have prepared an empty vid project which doesn't use any Frameworks so let's get to integrating react and actually before we start there is an option which VD provides us with which allows us to scaffold with project with react integrated right from the beginning and for that we just need to use value react for this template option and run the following comment but just to better understand this whole process and how the integration happens we're going to do all these steps manually and before we start we actually have to install all necessary npm packages such as libraries react react Dom and VD plugin which allows us to import react components and after all those libraries are installed we have to open up configuration file V.C config.js and in here let's import the plugin from the vdjs plug-in react package and then to include this plugin we have to call this function react in this array of plugins like so and that's basically it now we can just start developing react application so Aron starts with the main script file main.js let's remove Aron from this file and also rename this file on main. jsx since we're going to use jsx syntax in this file and also we have to fix the P to this file inside of index.html so let's go here and fix this extension right here as we can see we already have a de with an identifier app this will be a de where we're going to mount react application so let's create our root component we'll call the new file app.jsx and here we're going to use a simple example which will be basic counter component so let's import use State function from react then we're also going to create file with Styles and import them right here and then down here let's define our component function up so this function is going to have only one state variable which will be a counter initial value for this counter will be zero and right here let's define our template for this component so I'm going to add H1 element with the counter text and down Bellow we're going to create the button which is going to increment our counter and just to see if our counter gets incremented we're also going to show this variables value is the label for this button like so and now we'll register The Listener which will be fired when clicking on this button and inside of this listener we're basically going to update State variable count by incrementing it by one and finally at the bottom of this file let's export this component as a default expert and also just to check if we will be able to import CSS files with Styles and those Styles will be applied to our components let's create basic CSS file with the name up. CSS and in here I'm going to describe one rule for the H1 element and make the color of this element blue because previously I have already imported this CSS file in our component which is supposed to make this H1 Element blue so now that we have our root component in place we actually have to initialize react application inside of our main script so in here we're going to import react Dom Library from the react Dom client and also we're going to import our root component up from app.jsx in here we have to pass Dom element where we're going to mount our application into in this case we're going to mount it inside of element with an idea of up and eventually to render this application we're calling method render and as the parameter we're specifying our root component as the jsx and after that if we're going to take a look in a browser sure enough we're going to see work en counter and that means that react application was properly initialized so now just to see what Transformations are being applied to our react components we can use plug-in inspect which I have already pre-installed which allows us to open up this URL in a browser and see Transformations that happen to our inputs so in this case case once browser reads main. jsx file then it sees this import of app.jsx component then it fires the call to the server to fetch the code of this component and instead of giving us Z row content of this component VD applies react plugin to convert the content of this component into render function which will be recognized in the browser and then this function runs in a browser in this way we're seeing our counter component on the page and if we open up our inspector and take a look at the transformation which is happening with our component file we're going to see that this jsx syntax was converted into proper render function which will be recognized and run in the browser and this is it the whole process of react integration into vid project was pretty simple so just to recap we had to install three dependencies react react Dom and plugin for react and then we had to include this plugin inside vid configuration file in this plugins array and this is what actually allows us to create an import react components in our files so we can start developing our react applications in vid projects as we are used to we are slowly approaching the end of the course and in this final lesson we're going to take a look how to deploy V application and the service for the deployment that we are going to be using is called GitHub pages in fact there are a lot more services that provide support for when it comes to deployment and the deployment process is pretty simple for any of those services so we're going to review deployment steps by using GitHub Pages as always I have already prepared default vid application which we're going to deploy and actually before get into the deployment we need to make sure that that our repository exists on GitHub which in my case it does so we can go directly to the deployment we will not change any default configurations so after building our project all build files will be located inside this folder and this is exactly the folder which is going to be deployed so here in docs let's choose the option deployment to GitHub pages and our repository URL corresponds to this format where we have two URL segments first one is our GitHub username and the second one is the name of the repository so the only configuration option we have to specify will be the option called base and this option should contain the name of our repository so let's just go ahead and create configuration file vi. config.js in the root of this project from here we're going to expert configuration object which with only one option base where we're going to specify repository name which in my case is vit Das deployment and once again this is really important that this option Val should match repository name on GitHub so now we have to create new commit where we're going to include our configuration file let's specify any message and push this commit to GitHub after that let's just make sure that the new commit appears in the GitHub history of our project it is the second commit then let's open up settings tab the main branch of our repository is main so we're going to deploy this branch and now on the left side let's open up page called pages and in here we have to set up some deployment configurations firstly in this Source dropdown we have to choose option GitHub actions and then let's click this link create your own which is basically going to create an empty deployment configuration file let's clear out all this predefined content and specify our own configurations and these configurations are listed in vit docs so we just have to copy over this whole configuration paste it in that file and let's quickly go through some of the options specified in this file in here we can see which branch is going to be deployed and down here there are a couple of steps which will be executed during deployment for example in here we can see that the node version which is going to be used to build our project will be version 18 then we're going to install all npm dependencies by running npm install after that we're going to build a project by running npm run build and at the end once this folder with our built files will be created this folder will be deployed to GitHub Pages server then let's just give this configuration file a name for example deploy yml and click commit changes in here let's make sure that the new commit will be created on the main branch let's click commit changes once again and then we can see another new commit in the commit history this the commit with the configuration file for deployment we have just created and then if we open up top actions here we can actually see the new deployment task that is currently running and this is our deployment task so anytime we're going to push changes to the main branch it will automatically kick off the deployment process and by clicking on this task we can actually inspect what steps are executed during the deployment and once this deployment will be successfully finished we can once again open up settings tab and then go to Pages page and in here we will see the URL where our application will be available on the web so by following this URL we can see that our application was successfully deployed on GitHub pages and that's it we were able to successfully deploy V application on GitHub Pages server as we can see it was pretty simple process and if we decide to deploy our project by using another hosting provider the deployment process is going to be pretty simple as well and with that we are finishing this course about vid bundler