Sådan oprettes en Vue.js-app ved hjælp af enkeltfilskomponenter uden CLI.

En forståelse af Vue's enkeltfilskomponenter (SFC'er) og Node Package Manager (NPM) vil være nyttigt for denne artikel.

En rammes kommandolinjegrænseflade eller CLI er den foretrukne metode til at stilladsere et projekt. Det giver et startpunkt for filer, mapper og konfiguration. Dette stillads giver også en udviklings- og byggeproces. En udviklingsproces giver en måde at se opdateringer op, når du redigerer dit projekt. Bygningsprocessen opretter den endelige version af filer, der skal bruges i produktionen.

Installation og kørsel af Vue.js (“Vue”) kan udføres med et script-tag, der peger på Vue-indholdsleveringsnetværket (CDN). Ingen opbygning eller udviklingsproces er nødvendig. Men hvis du bruger Vue-enkeltfilskomponenter (SFC'er), skal du konvertere disse filer til noget, browseren kan forstå. Filerne skal konverteres til Hyper-Text Markup Language (HTML), Cascading Style Sheets (CSS) og JavaScript (JS). I dette tilfælde skal der bruges en udviklings- og byggeproces.

I stedet for at stole på Vue CLI til at stilladsere vores projekt og give os en udviklings- og byggeproces, bygger vi et projekt fra bunden. Vi opretter vores egen udviklings- og opbygningsproces ved hjælp af Webpack.

Hvad er Webpack?

Webpack er en modulbundler. Det fletter kode fra flere filer til en. Før Webpack inkluderede brugeren et script-tag for hver JavaScript-fil. Selvom browsere langsomt understøtter ES6-moduler, er Webpack fortsat den foretrukne måde at opbygge modulær kode på.

Udover at være en modulbundler kan Webpack også omdanne kode. For eksempel kan Webpack tage moderne JavaScript (ECMAScript 6+) og konvertere det til ECMAScript 5. Mens Webpack bundler selve koden, omdanner den koden med indlæser og plugins. Tænk på læssere og plugins som tilføjelser til Webpack.

Webpack og Vue

Komponenter med en fil giver os mulighed for at opbygge en hel komponent (struktur, stil og funktion) i en fil. Og de fleste kode redaktører giver syntaks fremhævning og fnug til disse SFC'er.

Bemærk, at filen slutter med .vue. Browseren ved ikke, hvad de skal gøre med denne udvidelse. Webpack omdanner denne fil ved hjælp af indlæsere og plugins til HTML, CSS og JS, som browseren kan forbruge.

Projektet: Byg en Hello World Vue-applikation ved hjælp af komponenter med en fil.

Trin 1: Opret projektstrukturen

Det mest basale Vue-projekt inkluderer en HTML-, JavaScript- og en Vue-fil (filen slutter på .vue ). Vi placerer disse filer i en mappe, der hedder src. Kildemappen hjælper os med at adskille den kode, vi skriver, fra den kode, Webpack til sidst bygger.

Da vi bruger Webpack, har vi brug for en Webpack-konfigurationsfil.

Derudover bruger vi en kompilator kaldet Babel. Babel giver os mulighed for at skrive ES6-kode, som den derefter kompilerer til ES5. Babel er en af ​​disse "tilføjelsesfunktioner" til Webpack. Babel har også brug for en konfigurationsfil.

Endelig, da vi bruger NPM, har vi også en node_modules-mappe og en package.json-fil. Disse oprettes automatisk, når vi initialiserer vores projekt som et NPM-projekt og begynder at installere vores afhængigheder.

For at komme i gang skal du oprette en mappe, der hedder hello-world. Fra kommandolinjen skal du skifte til den mappe og køre npm init. Følg vejledningen på skærmen for at oprette projektet. Opret derefter resten af ​​mapperne (undtagen node_modules) som beskrevet ovenfor. Din projektstruktur skal se sådan ud:

Trin 2: Installer afhængighederne

Her er en hurtig gennemgang af de afhængigheder, vi bruger:

vue : JavaScript-rammen

vue-loader og vue-template-compiler : Bruges til at konvertere vores Vue-filer til JavaScript.

webpack : Værktøjet, der giver os mulighed for at videregive vores kode gennem nogle transformationer og samle den i en fil.

webpack-cli: Nødvendigt for at køre Webpack-kommandoerne.

webpack-dev-server : Selvom det ikke er nødvendigt for vores lille projekt (da vi ikke fremsætter nogen HTTP-anmodninger), vil vi stadig “betjene” vores projekt fra en udviklingsserver.

babel-loader : Transform vores ES6-kode til ES5. (Det har brug for hjælp fra de næste to afhængigheder.)

@ babel / core og @ babel / preset-env : Babel i sig selv gør ikke noget ved din kode. Disse to “tilføjelser” giver os mulighed for at omdanne vores ES6-kode til ES5-kode.

css-loader: Tager den CSS, vi skriver i vores.vuefiler eller enhver CSS, vi muligvis importerer til nogen af ​​vores JavaScript-filer og løser stien til disse filer. Med andre ord skal du finde ud af, hvor CSS er. Dette er en anden læsser, der i sig selv ikke vil gøre meget. Vi har brug for den næste læsser til rent faktisk at gøre noget med CSS.

vue-style-loader : Tag den CSS, vi fik fra vores, css-loaderog indsprøjt den i vores HTML-fil. Dette opretter og indsprøjter et stilmærke i hovedet på vores HTML-dokument.

html-webpack-plugin : Tag vores index.html og indsprøjt vores medfølgende JavaScript-fil i hovedet. Kopier derefter denne fil tildistfolder.

rimraf : Giver os mulighed for at slette filer fra kommandolinjen. Dette vil være nyttigt, når vi bygger vores projekt flere gange. Vi bruger dette til at slette alle gamle builds.

Lad os installere disse afhængigheder nu. Fra kommandolinjen skal du køre:

npm install vue vue-loader vue-template-compiler webpack webpack-cli webpack-dev-server babel-loader @babel/core @babel/preset-env css-loader vue-style-loader html-webpack-plugin rimraf -D

Bemærk: “-D” i slutningen markerer hver afhængighed som en udviklingsafhængighed i vores package.json. Vi samler alle afhængigheder i en fil, så for vores lille projekt har vi ingen produktionsafhængigheder.

Trin 3: Opret filerne (undtagen vores Webpack-konfigurationsfil).

 {{ message }} export default { data() { return { message: 'Hello World', }; }, };   #app { font-size: 18px; font-family: 'Roboto', sans-serif; color: blue; } 
  Vue Hello World 
import Vue from 'vue'; import App from './App.vue'; new Vue({ el: '#app', render: h => h(App), });
module.exports = { presets: ['@babel/preset-env'], }

Up to this point, nothing should look too foreign. I’ve kept each file very basic. I’ve only added minimal CSS and JS to see our workflow in action.

Step 4: Instructing Webpack what to do

All the configuration Webpack needs access to is now present. We need to do two final things: Tell Webpack what to do and run Webpack.

Below is the Webpack configuration file (webpack.config.js). Create this file in the projects root directory. Line-by-line we’ll discuss what is occurring.

const HtmlWebpackPlugin = require('html-webpack-plugin'); const VueLoaderPlugin = require('vue-loader/lib/plugin'); module.exports = { entry: './src/main.js', module: { rules: [ { test: /\.js$/, use: 'babel-loader' }, { test: /\.vue$/, use: 'vue-loader' }, { test: /\.css$/, use: ['vue-style-loader', 'css-loader']}, ] }, plugins: [ new HtmlWebpackPlugin({ template: './src/index.html', }), new VueLoaderPlugin(), ] };

Lines 1 and 2: We are importing the two plugins we use below. Notice, our loaders don’t normally need to be imported, just our plugins. And in our case, thevue-loader (which we use in line 9) also needs a plugin to work (however, Babel, for example, does not).

Line 4: We export our configuration as an object. This gives us access to it when we run the Webpack commands.

Line 5: This is our entry module. Webpack needs a place to start. It looks in our main.js file and then starts to comb through our code from that point.

Line 6 and 7: This is the module object. Here, we primarily pass in an array of rules. Each rule tells Webpack how to handle certain files. So, while Webpack uses the entry point of main.js to start combing through our code, it uses the rules to transform our code.

Line 8 (rule): This rule instructs Webpack to use the babel-loader on any files which end with .js. Remember, Babel will transform ES6+ to ES5.

Line 9 (rule): This rule instructs Webpack to use vue-loader(and don’t forget the associated plugin on line 17) to transform our .vue files into JavaScript.

Line 10 (rule): Sometimes we want to pass a file through two loaders. Counterintuitively, Webpack will pass the file from right to left instead of left to right. Here we are using two loaders and saying to Webpack: “get my CSS from my Vue file or any JavaScript files(css-loader) and inject it into my HTML as a style tag (vue-style-loader).

Lines 11 and 12: Close out our rules array and module object.

Lines 13: Create a plugins array. Here we will add the two plugins we need.

Line: 14 -16 (plugin): The HtmlWebpackPlugin takes the location of our index.html file and adds our bundled JavaScript file to it via a script tag. This plugin will also copy the HTML file to our distribution folder when we build our project.

Line 17 (plugin): The VueLoaderPlugin works with our vue-loader to parse our .vue files.

Line 18: Close out the plugins array.

Line 19: Close out the Webpack object that we are exporting.

Step 5: Setting up our package.json file so we can run Webpack

Our configuration is complete, now we want to see our application. Ideally, as we make changes to our application, the browser would update automatically. This is possible with webpack-dev-server.

Delete the test script in our package.json file, and replace it with a script to serve our application:

 { "name": "hello-world", "version": "1.0.0", "description": "", "main": "main.js", "scripts": { "serve": "webpack-dev-server --mode development" }, "author": "", "license": "ISC", "devDependencies": { "@babel/core": "^7.1.6", "@babel/preset-env": "^7.1.6", "babel-loader": "^8.0.4", "css-loader": "^1.0.1", "html-webpack-plugin": "^3.2.0", "rimraf": "^2.6.2", "vue": "^2.5.17", "vue-loader": "^15.4.2", "vue-style-loader": "^4.1.2", "vue-template-compiler": "^2.5.17", "webpack": "^4.26.0", "webpack-cli": "^3.1.2", "webpack-dev-server": "^3.1.10" }, "dependencies": {} }

The name of this command is your choice. I chose to call mine serve since we will be serving our application.

From our terminal or command line, we can run npm run serve and that in turn will run webpack-dev-server --mode development .

The --mode development is what’s called a flag or option. We haven’t talked about this, but it essentially instructs Webpack that you are in development mode. We can also pass in --mode production which we will do when we build our project. These aren’t necessarily required for Webpack to work. Without these, you will get a warning message telling you to provide a mode when you run Webpack .

I say “necessarily required” because Webpack will minimize our code in production mode but not in development. So, don’t think those commands don’t do anything–they do.

Let’s run npm run serve and see what happens.

When we run npm run serve we get some output in our terminal. And, if everything goes well:

And if we scroll up a bit:

Point your browser to //localhost:8080. You will see your Blue Hello World message in Roboto font.

Now, let’s update the project and change the message to Hello Universe. Notice that the webpage refreshes automatically. That’s great, right? Can you think of a downside?

Let’s change the application just a bit and include an input which we will bind a variable to (with v-model). We will output the variable in an

tag below the input. I’ve also updated the styling section to style the message now. Our App.vuefile should look like this:

{{ message }}

export default { data() { return { message: 'Hello world!', }; }, }; .message { font-size: 18px; font-family: 'Roboto', sans-serif; color: blue; }

When we serve our application, we will have an input with a message of Hello World below it. The input is bound to the message variable, so as we type, we change the

content. Go ahead, type into the input to change the

content.

Now go back to your editor, and below the

tag, add the following:

Some Other Message

Save your App.vue and watch what happens.

The h2 we just updated by typing in our input reverted back to Hello World. This is because the browser actually refreshes, and the script tag and page are loaded again. In other words, we were not able to maintain the state of our application. This may not seem like a big deal, but as you are testing your application and adding data to it, it will be frustrating if your app “resets” every time. Fortunately, Webpack offers us a solution called Hot Module Replacement.

The hot module replacement is a plugin provided by Webpack itself. Up until this point, we have not used the Webpack object itself in our configuration file. However, we will now import Webpack so we can access the plugin.

In addition to the plugin, we will pass one additional option to Webpack, the devServer option. In that option, we will set hot to true. Also, we will make an (optional) update to our build workflow: We will open the browser window automatically when we run npm run serve. We do this by setting open to true which is also inside the devServer option.

const HtmlWebpackPlugin = require('html-webpack-plugin'); const VueLoaderPlugin = require('vue-loader/lib/plugin'); const webpack = require('webpack'); module.exports = { entry: './src/main.js', module: { rules: [ { test: /\.js$/, use: 'babel-loader' }, { test: /\.vue$/, use: 'vue-loader' }, { test: /\.css$/, use: ['vue-style-loader', 'css-loader']}, ] }, devServer: { open: true, hot: true, }, plugins: [ new HtmlWebpackPlugin({ template: './src/index.html', }), new VueLoaderPlugin(), new webpack.HotModuleReplacementPlugin(), ] };

Notice that we’ve imported Webpack so we could access the hotModuleReplacementPlugin. We’ve added that to the plugins array, and then told Webpack to use it with hot: true. We open the browser window automatically when we serve the application with open: true.

Run npm run serve:

The browser window should open, and if you open your dev tools, you should notice a slight change in the output. It now tells us hot module replacement is enabled. Let’s type in our input to change the

content. Then, change theh3 tag to read: One More Message.

Save your file and notice what happens.

The browser doesn't refresh, but our

change is reflected! The message we typed in the input remains, but the h3 updates. This allows our application to keep it’s state while we edit it.

Step 7: Building our project

So far, we’ve served our application. But, what if we want to build our application so we can distribute it?

If you noticed, when we serve our application, no files are created. Webpack creates a version of these files that only exist in temporary memory. If we want to distribute our Hello World app to our client, we need to build the project.

This is very simple. Just like before, we will create a script in our package.json file to tell Webpack to build our project. We will use webpack as the command instead of webpack-dev-server. We will pass in the --mode production flag as well.

We will also use the rimraf package first to delete any previous builds we may have. We do this simply by rimraf dist.

dist is the folder Webpack will automatically create when it builds our project. “Dist” is short for distribution–i.e. we are “distributing” our applications code.

The rimraf dist command is telling therimraf package to delete the dist directory. Make sure you don’t rimraf src by accident!

Webpack also offers a plugin that will accomplish this cleaning process called clean-webpack-plugin. I chose dist show an alternative way.

Our package.json file should look like this:

{ "name": "hello-world", "version": "1.0.0", "description": "", "main": "main.js", "scripts": { "clean": "rimraf dist", "build": "npm run clean && webpack --mode production", "serve": "webpack-dev-server --mode development" }, "author": "", "license": "ISC", "devDependencies": { "@babel/core": "^7.1.6", "@babel/preset-env": "^7.1.6", "babel-loader": "^8.0.4", "css-loader": "^1.0.1", "html-webpack-plugin": "^3.2.0", "rimraf": "^2.6.2", "vue": "^2.5.17", "vue-loader": "^15.4.2", "vue-style-loader": "^4.1.2", "vue-template-compiler": "^2.5.17", "webpack": "^4.26.0", "webpack-cli": "^3.1.2", "webpack-dev-server": "^3.1.10" }, "dependencies": {} }

There are three things to notice:

  1. I’ve created a separate clean script so we can run it independently of our build script.
  2. npm run build will call the independent clean script we’ve created.
  3. I have && between npm run clean and webpack. This instruction says: “run npm run clean first, then run webpack”.

Let’s build the project.

npm run build

Webpack creates a dist directory, and our code is inside. Since our code makes no HTTP requests, we can simply open our index.html file in our browser and it will work as expected.

If we had code that was making HTTP requests, we would run into some cross-origin errors as we made those requests. We would need to run that project from a server for it to work.

Let’s examine the index.html that Webpack created in the browser and the code editor.

If we open it in our editor or take a look at the source code in our dev tools you will see Webpack injected the script tag. In our editor though, you won’t see the styles because the style tag is injected dynamically at runtime with JavaScript!

Also, notice our development console information is no longer present. This is because we passed the --production flag to Webpack.

Konklusion

At forstå byggeprocessen bag de rammer, du bruger, hjælper dig med bedre at forstå selve rammen. Tag dig tid til at forsøge at opbygge et Angular, React eller et andet Vue-projekt uden brug af de respektive CLI'er. Eller bygg bare et grundlæggende websted med tre filer (index.html, styles.css og app.js), men brug Webpack til at betjene og oprette en produktionsversion.

Tak for læsningen!

woz