Node/Express中使用Pug模板引擎实现动态模板渲染
Got it, let's get this sorted for you—since you want to standardize on Pug for your Node.js chat app and replace that Mustache dynamic rendering, here are two straightforward approaches to replicate your existing functionality:
Approach 1: Client-side Pug Rendering (Quick Drop-in Replacement)
This mirrors your original Mustache workflow closely, with minimal changes to your existing code structure:
Step 1: Update your Pug template (index.pug)
Replace the Mustache script template with a Pug-specific template, and add the client-side Pug library:
.chat__main ol#messages.chat__messages .chat__footer form#message-form(action="") input(type="text" name="message" placeholder="Message" autofocus autocomplete="off") button Send button#send-location Send location //- Pug template for messages (uses text/x-pug-template type) script#message-template(type="text/x-pug-template") p= text .message-meta Sent by: #{from} //- Example of inline text interpolation in Pug //- Include dependencies, plus the client-side Pug library script(src="/socket.io/socket.io.js") script(src="javascripts/libs/jquery-3.2.1.min.js") script(src="javascripts/libs/moment.js") script(src="https://cdn.jsdelivr.net/npm/pug@3.0.2/lib/pug.min.js") // Or host the file locally script(src="javascripts/index.js")
Step 2: Modify your front-end JS (index.js)
Swap out Mustache.render for Pug's compile-and-render flow. To optimize, compile the template once instead of on every message:
// Pre-compile the template once on page load (avoids repeated work) const messageTemplate = $('#message-template').html(); const renderMessage = pug.compile(messageTemplate); socket.on('newMessage', message => { // Use the pre-compiled function to generate HTML const html = renderMessage({ text: message.text, from: message.from }); $('#messages').append(html); });
Approach 2: Server-side Precompiled Templates (Production-Friendly)
For better performance (avoids loading the full Pug library client-side), precompile your Pug templates into JavaScript functions on the server and pass them to the front-end:
Step 1: Create a standalone message template (message.pug)
p= text .message-meta Sent by: #{from}
Step 2: Precompile the template in your Node.js backend
Use pug.compileClient to turn the Pug template into a reusable JS function:
const pug = require('pug'); const fs = require('fs'); // Compile the template into a client-side function const compiledTemplate = pug.compileClient( fs.readFileSync('./views/message.pug', 'utf8'), { name: 'renderMessage' } // Name the function for easy global access ); // Pass the compiled function to your index.pug template app.get('/', (req, res) => { res.render('index', { messageRenderFn: compiledTemplate }); });
Step 3: Inject the compiled function into your index.pug
.chat__main //- Same chat UI structure as before ol#messages.chat__messages .chat__footer form#message-form(action="") input(type="text" name="message" placeholder="Message" autofocus autocomplete="off") button Send button#send-location Send location //- Inject the precompiled rendering function directly into the page script. !{messageRenderFn} //- No need for the client-side Pug library now! script(src="/socket.io/socket.io.js") script(src="javascripts/libs/jquery-3.2.1.min.js") script(src="javascripts/libs/moment.js") script(src="javascripts/index.js")
Step 4: Use the precompiled function in index.js
socket.on('newMessage', message => { // The renderMessage function is already available globally const html = renderMessage({ text: message.text, from: message.from }); $('#messages').append(html); });
Key Notes:
- Pug uses
=for variable interpolation (instead of Mustache's{{}}), and#{}for inline interpolation inside text blocks. - Approach 1 is great for development speed; Approach 2 is better for production as it reduces client-side bundle size and improves load times.
- Pug supports more logic out of the box than Mustache—you can add conditionals, loops, and mixins directly in your template (e.g.,
if from === 'Admin' .admin-messageto style system messages differently).
内容的提问来源于stack exchange,提问作者Eazy

