预编译 pug 模板并保存对 htmlWebpackPlugin.options 的访问



我决定从ejs转移到pug作为我的 webpack 项目中的模板引擎。我需要的是预编译的静态输出(在开发或生产模式下)。另外,我需要通过编译过程将数据传递给模板,并且我使用自定义的htmlWebpackPlugin选项。项目结构如下:

root
|--package.json
|--webpack.configs // .dev.js, build.js
|--data.json
|--layout.pug
|--app
|--|--index.js
|--|--views
|--|--|--index.pug
|--|--|--includes
|--|--|--|--nav.pug
|--|--|--|--footer.pug
|--assets
|--|--(styles, images...)

我找到并尝试的第一种方法是将数据传递到入口点(在index.js编译局部变量并通过innerHTML =将它们插入页面)。这种方式绝对不适合我,因为我需要 100% 预编译的静态输出而无需运行时 HTML 插入。然后乐趣开始了...

例如,我需要创建导航。我的导航模式如下:

module.exports.nav = [
{
text: 'Home',
href: '/'
},
{
text: 'Offers',
href: '/offers.html'
},
{
text: 'Subnav Parent Test',
isSubnavTrigger: true
},
{
text: 'Subnav Item',
href: '/test.html',
isSubnavItem: true,
subnavParent: 'Subnav Parent Test'
}
]

和哈巴狗部分为这个app/views/includes/nav.pug

nav.navbar(role="navigation", ariaLabel="navigation")
.container
.navbar-brand
a.navbar-item(href="/")
img(src="/assets/images/logo.png", alt=title)
.navbar-menu(id="navbar-menu")
.navbar-start
.navbar-end
for link, index in nav
//- TODO: isActive
if !link.isSubnavTrigger && !link.isSubnavItem
a(href=link.href, class="navbar-item")= link.text
else if link.isSubnavTrigger
.navbar-item.has-dropdown.is-hoverable
a.navbar-link= link.text
.navbar-dropdown
- var parent = link.text
- var dd = nav.filter(_item => _item.subnavParent === 
parent)
each dd_link in dd
a.navbar-item(href=dd_link.href)= dd_link.text

该部分包含在通用布局layout.pug中:

- var { title, nav } = htmlWebpackPlugin.options;
<!DOCTYPE html>
html(lang="en")
head
title= title + 'Pug Webpack Test'
block metas
body
header
include ./app/views/includes/nav.pug
main
block content
footer  
include ./app/views/includes/footer.pug

希望app/views/includes/nav.pug将插值nav变量。

所以我发现了 2 种情况:使用module -> rules -> loader和内联加载器到 HTMLWebpackPlugin。

第一。webpack.config.js设置:

module.exports = {
module: {
rules: [
//...
{
test: /.pug$/,
use: ['file-loader?name=[path][name].html', 'pug-html-loader?pretty&exports=false']
}
//...
],
},
plugins: [
//...
new HtmlWebpackPlugin({
template: './layout.pug',
filename: 'index.html',
title: 'siteTitle',
nav: nav  // required somewhere at the top of the file
})
]
}

在这种情况下,我无法将选项从htmlWebpackPlugin传递到模板中。如layout.pug中所述,我尝试从选项中破坏titlenav字段并得到编译错误:Cannot read property 'options' of undefined

第二种情况。webpack.config.js

module.exports = {
module: {
rules: [
//...
// Removed PUG loaders
//...
],
},
plugins: [
//...
new HtmlWebpackPlugin({
template: '!!pug-loader!./layout.pug', // <- inlined loader
filename: 'index.html',
title: 'siteTitle',
nav: nav  // required somewhere at the top of the file
})
]
}
// by the way, in case of EJS I've been using exactly this approach
// and it worked out pretty well with partials

这种方法完美地编译了layout.pug,从htmlWebpackPlugin中获取的选项,直到它不包含包含的部分。我需要将我的nav传递给相应的部分并从那里渲染导航。并且部分开始将错误抛入编译中,就好像它不理解pug并且需要加载器一样:

ERROR in ./app/views/includes/nav.pug 13:12
Module parse failed: Unexpected token (13:12)
You may need an appropriate loader to handle this file type.
|       .navbar-start
|       .navbar-end
>         for link, index in nav
|           //- TODO: isActive
|           if !link.isSubnavTrigger && !link.isSubnavItem
@ ./app/views/index.pug (c:/_npmg/node_modules/pug-loader!./app/views/index.pug) 4:514-543

我完全一团糟。我不想回到ejs,但如果我找不到答案,似乎我将不得不这样做。

谢谢转发。

解决了。

答案包括两个结论:

  1. 使用适当的加载程序。

    唯一适合我需求的加载器是pug-loader(不是pug-html-loader也不是多个加载器的链)。参考在这里,但用两个词:

    pug-loader:返回一个函数

    pug-html-loader:返回一个字符串,因此它是静态的,不能传递任何选项

    因此,有关此的最终webpack.config.js设置是:

module.exports = {
module: {
rules: [
//...
test: /.pug$/,
use: [
{loader: 'pug-loader'}
]
//...
],
},
plugins: [
//...
new HtmlWebpackPlugin({
template: './layout.pug', // <- NOT inlined loader
filename: 'index.html',
title: 'siteTitle',
nav: nav  // required somewhere at the top of the file
})
]
}
  1. 部件不会从需要从布局继承变量。

    因此,由于我想使用来自htmlWebpackPlugin.options的数据,我必须为这些数据声明变量,而不是在公共布局文件中,而是在部分本身中:

// app/views/partials/nav.pug
- var { nav } = htmlWebpackPlugin.options
nav.navbar(... and the other code you've seen above)

如果有人遇到这个问题,这是100%的工作方法。

我想通知 OP 他的解决方案,但我无法发表评论。

HtmlWebpackPluginpug-loader可以很好地协同工作。而不是使用 :

// webpack.config file
new HtmlWebpackPlugin({
template: './layout.pug',
filename: 'index.html',
myContent: 'loremp ipsum'
})
// app/views/partials/nav.pug
- var { myContent } = htmlWebpackPlugin.options
p= myContent

您可以使用以下语法:

// webpack.config file
new HtmlWebpackPlugin({
template: './layout.pug',
filename: 'index.html',
templateParameters: {
myContent: 'loremp ipsum'   
}
})
// app/views/partials/nav.pug
p= myContent

它适用于所有哈巴狗引擎功能,我们获得了更多可读的模板。

相关内容

  • 没有找到相关文章

最新更新