So erstellen Sie eine Vue.js-App mit Einzeldateikomponenten ohne CLI.

Ein Verständnis der Single-File-Komponenten (SFCs) und des Node Package Managers (NPM) von Vue ist für diesen Artikel hilfreich.

Die Befehlszeilenschnittstelle (CLI) eines Frameworks ist die bevorzugte Methode, um ein Projekt zu erstellen. Es bietet einen Ausgangspunkt für Dateien, Ordner und Konfiguration. Dieses Gerüst bietet auch einen Entwicklungs- und Bauprozess. Ein Entwicklungsprozess bietet eine Möglichkeit, Aktualisierungen beim Bearbeiten Ihres Projekts anzuzeigen. Der Erstellungsprozess erstellt die endgültige Version der Dateien, die in der Produktion verwendet werden sollen.

Die Installation und Ausführung von Vue.js („Vue“) kann mit einem Skript-Tag erfolgen, das auf das Vue Content Delivery Network (CDN) verweist. Es ist kein Build- oder Entwicklungsprozess erforderlich. Wenn Sie jedoch Vue-Single-File-Komponenten (SFCs) verwenden, müssen Sie diese Dateien in etwas konvertieren, das der Browser verstehen kann. Die Dateien müssen in Hyper-Text Markup Language (HTML), Cascading Style Sheets (CSS) und JavaScript (JS) konvertiert werden. In diesem Fall muss ein Entwicklungs- und Erstellungsprozess verwendet werden.

Anstatt uns auf die Vue-CLI zu verlassen, um unser Projekt zu strukturieren und uns einen Entwicklungs- und Erstellungsprozess zu bieten, werden wir ein Projekt von Grund auf neu erstellen. Wir werden unseren eigenen Entwicklungs- und Erstellungsprozess mit Webpack erstellen.

Was ist Webpack?

Webpack ist ein Modulbündler. Es führt Code aus mehreren Dateien zu einer zusammen. Vor Webpack hat der Benutzer für jede JavaScript-Datei ein Skript-Tag eingefügt. Obwohl Browser ES6-Module langsam unterstützen, ist Webpack weiterhin die bevorzugte Methode zum Erstellen von modularem Code.

Webpack ist nicht nur ein Modulbündler, sondern kann auch Code transformieren. Beispielsweise kann Webpack modernes JavaScript (ECMAScript 6+) verwenden und in ECMAScript 5 konvertieren. Während Webpack den Code selbst bündelt , transformiert es den Code mit Loadern und Plugins. Stellen Sie sich Loader und Plugins als Add-Ons für Webpack vor.

Webpack und Vue

Mit Einzeldateikomponenten können wir eine gesamte Komponente (Struktur, Stil und Funktion) in einer Datei erstellen. Die meisten Code-Editoren bieten Syntaxhervorhebung und Flusen für diese SFCs.

Beachten Sie, dass die Datei mit .vue endet. Der Browser weiß nicht, was er mit dieser Erweiterung tun soll. Webpack wandelt diese Datei mithilfe von Loadern und Plugins in HTML, CSS und JS um, die der Browser verwenden kann.

Das Projekt: Erstellen einer Hello World Vue-Anwendung mit Einzeldateikomponenten.

Schritt 1: Erstellen Sie die Projektstruktur

Das grundlegendste Vue-Projekt umfasst eine HTML-, JavaScript- und eine Vue-Datei (die Datei endet mit .vue ). Wir werden diese Dateien in einem Ordner namens platzieren src. Der Quellordner hilft uns dabei, den Code, den wir schreiben, von dem Code zu trennen, den Webpack schließlich erstellen wird.

Da wir Webpack verwenden werden, benötigen wir eine Webpack-Konfigurationsdatei.

Zusätzlich werden wir einen Compiler namens Babel verwenden. Mit Babel können wir ES6-Code schreiben, der dann in ES5 kompiliert wird. Babel ist eine dieser „Zusatzfunktionen“ für Webpack. Babel benötigt auch eine Konfigurationsdatei.

Da wir NPM verwenden, haben wir schließlich auch einen Ordner node_modules und eine Datei package.json. Diese werden automatisch erstellt, wenn wir unser Projekt als NPM-Projekt initialisieren und mit der Installation unserer Abhängigkeiten beginnen.

Erstellen Sie zunächst einen Ordner mit dem Namen hello-world. Wechseln Sie in der Befehlszeile in dieses Verzeichnis und führen Sie es aus npm init. Befolgen Sie die Anweisungen auf dem Bildschirm, um das Projekt zu erstellen. Erstellen Sie dann den Rest der Ordner (außer node_modules) wie oben beschrieben. Ihre Projektstruktur sollte folgendermaßen aussehen:

Schritt 2: Installieren Sie die Abhängigkeiten

Hier ist ein kurzer Überblick über die Abhängigkeiten, die wir verwenden:

vue : Das JavaScript-Framework

vue-loader und vue-template-compiler : Dient zum Konvertieren unserer Vue-Dateien in JavaScript.

Webpack : Das Tool, mit dem wir unseren Code durch einige Transformationen führen und in einer Datei bündeln können.

webpack-cli: Wird benötigt, um die Webpack-Befehle auszuführen.

webpack-dev-server : Obwohl für unser kleines Projekt nicht benötigt (da wir keine HTTP-Anfragen stellen), werden wir unser Projekt dennoch von einem Entwicklungsserver aus "bedienen".

babel-loader : Verwandeln Sie unseren ES6-Code in ES5. (Es braucht Hilfe von den nächsten beiden Abhängigkeiten.)

@ babel / core und @ babel / preset-env : Babel selbst macht nichts mit Ihrem Code. Mit diesen beiden „Add-Ons“ können wir unseren ES6-Code in ES5-Code umwandeln.

CSS -Loader: Nimmt das CSS, das wir in unser schreiben.vueDateien oder CSS, die wir möglicherweise in eine unserer JavaScript-Dateien importieren und den Pfad zu diesen Dateien auflösen. Mit anderen Worten, finden Sie heraus, wo sich das CSS befindet. Dies ist ein weiterer Lader, der allein nicht viel bringt. Wir brauchen den nächsten Loader, um tatsächlich etwas mit dem CSS zu tun.

vue-style-loader : Nehmen Sie das CSS, das wir von unserem erhalten haben, css-loaderund fügen Sie es in unsere HTML-Datei ein. Dadurch wird ein Style-Tag erstellt und in den Kopf unseres HTML-Dokuments eingefügt.

html-webpack-plugin : Nehmen Sie unsere index.html und fügen Sie unsere gebündelte JavaScript-Datei in den Kopf ein. Kopieren Sie dann diese Datei in diedistOrdner.

rimraf : Ermöglicht es uns, über die Befehlszeile Dateien zu löschen. Dies ist praktisch, wenn wir unser Projekt mehrmals erstellen. Wir werden dies verwenden, um alte Builds zu löschen.

Lassen Sie uns diese Abhängigkeiten jetzt installieren. Führen Sie in der Befehlszeile Folgendes aus:

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

Hinweis: Das "-D" am Ende markiert jede Abhängigkeit als Entwicklungsabhängigkeit in unserer package.json. Wir bündeln alle Abhängigkeiten in einer Datei, sodass wir für unser kleines Projekt keine Produktionsabhängigkeiten haben.

Schritt 3: Erstellen Sie die Dateien (mit Ausnahme unserer Webpack-Konfigurationsdatei).

 {{ 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'], }

Bis zu diesem Punkt sollte nichts zu fremd aussehen. Ich habe jede Datei sehr einfach gehalten. Ich habe nur minimales CSS und JS hinzugefügt, um unseren Workflow in Aktion zu sehen.

Schritt 4: Weisen Sie Webpack an, was zu tun ist

Die gesamte Konfiguration, auf die Webpack Zugriff benötigt, ist jetzt vorhanden. Wir müssen zwei letzte Dinge tun: Sagen Sie Webpack, was zu tun ist, und führen Sie Webpack aus.

Unten finden Sie die Webpack-Konfigurationsdatei ( webpack.config.js). Erstellen Sie diese Datei im Projektstammverzeichnis. Zeile für Zeile werden wir diskutieren, was passiert.

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(), ] };

Zeilen 1 und 2: Wir importieren die beiden unten verwendeten Plugins. Beachten Sie, dass unsere Lader normalerweise nicht importiert werden müssen, sondern nur unsere Plugins. Und in unserem Fall dievue-loader (das wir in Zeile 9 verwenden) benötigt auch ein Plugin, um zu funktionieren (Babel zum Beispiel jedoch nicht).

Zeile 4: Wir exportieren unsere Konfiguration als Objekt. Dies gibt uns Zugriff darauf, wenn wir die Webpack-Befehle ausführen.

Zeile 5: Dies ist unser Eingabemodul. Webpack braucht einen Startpunkt. Es sieht in unserer main.jsDatei aus und beginnt dann, ab diesem Punkt unseren Code zu durchkämmen.

Zeile 6 und 7: Dies ist das Modulobjekt. Hier übergeben wir hauptsächlich eine Reihe von Regeln. Jede Regel teilt Webpack mit, wie mit bestimmten Dateien umgegangen werden soll. Während Webpack den Einstiegspunkt verwendet main.js, um unseren Code zu durchkämmen, verwendet es die Regeln, um unseren Code zu transformieren.

Zeile 8 (Regel): Diese Regel weist Webpack an, die babel-loaderfür alle Dateien zu verwenden, die mit enden .js. Denken Sie daran, Babel wird ES6 + in ES5 umwandeln.

Zeile 9 (Regel): Diese Regel weist Webpack zur Verwendung anvue-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.

Conclusion

Understanding the build process behind the frameworks you use will help you to better understand the framework itself. Take some time to try to build an Angular, React or another Vue Project without the use of the respective CLIs. Or, just build a basic three-file site (index.html, styles.css, and app.js), but use Webpack to serve and build a production version.

Thanks for reading!

woz