Kompilieren unseres Express Servers mit Webpack

In diesem Artikel richten wir serverseitiges Rendern ein, indem wir sogar Serverdateien mit Webpack verarbeiten. Wir werden webpack auf ein neues Ziel setzen. Knoten. Dadurch können wir serverseitig mehr als nur Javascript kompilieren.

Wir fangen dort an, wo wir aufgehört habender letzte Artikel Wenn Sie Nachholbedarf haben:

git clone 
cd webpack-course
git checkout ssr-webpack
npm install

Webpack-Zielknoten

Also haben wir letztes Mal versucht, unsere zu rendern AppRoot Komponente stießen wir auf ein Problem. Node, Babel und Express mit all ihrer Kraft verstehen keine Bilder oder Abschriften. Node kann sie anfordern oder in ES6 importieren, aber Node erwartet immer Javascript, also wirft es das Bild an den Javascript-Compiler und dies geschieht.

Knoten brach bei Markdown

Cool, richtig. Es stellt sich also heraus, dass dies ziemlich lösbar ist. Es gibt ein paar Lösungen wie webpack-isomorphic-tools die die require-Anweisung entführen und im Knoten auf der Serverseite ersetzen. Und obwohl das cool ist, ist es seitdem auch veraltet target: "node" kam zur Webpack-Konfiguration.

Zielknoten

Was wir tun müssen, ist Webpack zur Verarbeitung zu verwenden express.js, damit Bilder und Markdown ordnungsgemäß verarbeitet werden, und führen Sie dann die neue Datei mit node. Wir wollen eine neue “Server”-Konfiguration erstellen und ein neues Paket hinzufügen.

touch config/webpack.server.js
npm install webpack-node-externals

Fügen Sie Folgendes hinzu config/webpack.server.js:

const path = require("path")
const webpack = require("webpack")
const ExtractTextPlugin = require("extract-text-webpack-plugin")
var nodeExternals = require("webpack-node-externals") module.exports = env => { return { target: "node", externals: nodeExternals(), entry: { server: ["./src/server/main.js"] }, output: { filename: "[name]-bundle.js", path: path.resolve(__dirname, "../build"), }, module: { rules: [{ test: /\.js$/, exclude: /node_modules/, use: [ { loader: "babel-loader" }] }, { test: /\.css$/, use: ExtractTextPlugin.extract({ fallback: "style-loader", use: { loader: "css-loader", options: { minimize: true } } }) }, { test: /\.jpg$/, use: [{ loader: "file-loader", options: { name: "/images/[name].[ext]", } } ] }, { test: /\.md$/, use: [{ loader: "markdown-with-front-matter-loader" }] } ] }, plugins: [new ExtractTextPlugin("[name].css"), new webpack.DefinePlugin({ "process.env": { NODE_ENV: JSON.stringify(env.NODE_ENV) } }), new webpack.NamedModulesPlugin() ] }
}

Kühl. Beachten Sie also die ersten beiden Zeilen unserer Konfiguration.

target: "node",
externals: nodeExternals(),

Das ist der Kern des Unterschieds. Mit target node weisen wir webpack an, unsere Assets für node statt für das Web zu bündeln. target: "web" ist das Standardziel. Diese Änderung ermöglicht es webpack, mit der sich ständig verändernden Welt von zu wachsenGeräteziele.

Externals bedeutet, was Webpack zur Kompilierzeit nicht bündeln wird. Dasexternals Option könnte so einfach sein wie /node_modules/. In diesem Fall verwenden wir eine Funktion, die aus importiert wird webpack-node-externals Paket. Dies wird unsere Bundles weit nach unten bringen und trotzdem alle Pakete zur Laufzeit über den normalen Knoten laden require().

In dem output Abschnitt fügen wir einen neuen Ordner hinzu, den Build-Ordner, also das kompilierte Bundle, sitzt nicht in einem öffentlichen Verzeichnis wie dist. Also im Terminal:

mkdir build

Im package.jsonwerden wir unsere Skripte aktualisieren.

"build:server": "BABEL_ENV=production webpack --config=config/webpack.server.js --env.NODE_ENV=production",

Jetzt ausführen:

npm run build:server

Nehmen express.js und verwandle es in server-bundle.js.

Server gebündelt

In Ihrem Build-Verzeichnis finden Sie eine server-bundle.js und einen Bilderordner.

Jetzt werden wir unser Prod-Skript ändern package.json auf diese neue Datei zeigen.

"prod": "NODE_ENV=production node build/server-bundle.js",

Wir können das Hacky-Zeug darin entfernen AppRoot.js oben und ersetzen Sie es durch normale Anforderungen.

const MarkdownData = require("../../data/post.md")
const imagePath = require("../images/link.jpg")

Also, wenn wir laufen npm run dev wir sollten das sehen index.ejs und main-bundle.jsheißes Nachladen wie gewohnt. Style-Tags werden über den Style-Loader eingefügt.

Wenn wir laufen npm run build:server und npm run prod Wir führen den Server aus und sehen den Markdown direkt im HTML.

Quelltext anzeigen

Lassen Sie uns dies auch auf der Entwicklungsseite tun. Im package.json:

"dev": "node --inspect build/server-bundle.js"

Und schließlich haben wir eine zusätzliche Datei, die beim Server-Build ausgegeben wird. Das Bild. Lass uns ändern webpack.server.js diese Datei nicht auszugeben.

{ test: /\.jpg$/, use: [{ loader: "file-loader", options: { name: "/images/[name].[ext]", emitFile: false } } ]
},

In Summe

Wir haben es geschafft. Wir haben die Tür zu einer weiteren Verwendung für Webpack geöffnet. Es kann Servercode mit a kompilieren node build target, um alle Dateitypen zu integrieren, die die Ladeprogramme zulassen. Mit einer neuen Konfigurationsdatei erstellen wir ein Server-Bundle, das Markdown und andere Asset-Typen im Rendering enthält. Wir können vorerst dieselbe Serverkonfiguration in Produktion und Entwicklung verwenden, aber wir werden sehen, wie wir diese aufteilen und warum.

git checkout ssr-webpack-final

Als nächstes

Bei unseren Bemühungen, die ultimative Webpack-Boilerplate zu erstellen, sind wir noch nicht ganz am Ziel. Eine Sache, die unseren Fortschritt behindert, ist, dass wir Webpack nur von der Befehlszeile aus verwendet haben. In der nächsten Folge werden wir uns die Verwendung von Webpack als Javascript-Funktion ansehen, um unseren Server nach der Webpack-Kompilierung zu starten und neu zu starten. Dieser nächste Schritt trennt die Profis von denen, die nie die wahre Leistungsfähigkeit von Webpack erfahren. Bleib dran.

Similar Posts

Leave a Reply

Your email address will not be published.