makefile静态编译_建立您的静态网站的光彩的Makefile

makefile静态编译

Nowadays static websites are back in fashion. And it even has a name: JAMStack. After years of sophistication and dynamism, we rediscovered the fact that static websites are pretty fast. Sometimes we even overestimated the benefits of dynamism in our websites. And even when we need it, there are a lot of good frontend javascript frameworks out there which let us download JSON data and only build the dynamic part in the browser.

如今,静态网站已重新流行。 它甚至有一个名称: JAMStack 。 经过多年的完善和动态处理,我们重新发现了静态网站非常快的事实。 有时,我们甚至高估了网站动态性的好处。 即使我们需要它,也有很多不错的前端javascript框架,这些框架使我们可以下载JSON数据并仅在浏览器中构建动态部分。

Consequently, there are also tons of tools to create static websites and build them. You have Jekyll, Gatsby, Hugo and so many more. All of these are really good tools. But today I wanted to show you how you can do it with a very old school tool called: Make.

因此,还有大量工具可以创建静态网站并进行构建。 您有JekyllGatsbyHugo等等。 所有这些都是非常好的工具。 但是今天我想向您展示如何使用一个非常古老的学校工具: Make来做到这一点。

If you don’t care about the explanation and just wanna see the code, shame on you but here is the Gist.

如果您不在乎解释,只是想看代码,可耻的是,这就是Gist

为什么做? (Why Make ?)

There are a few reasons for it. The first one is that Make is one of these classic tools that you probably already have. The first version was released in 1976. No need to install a new tool which in turn forces you to install a programming language you don’t use. In fact most of Make is built on top of shell scripts which you most likely know already.

有几个原因。 第一个是Make是您可能已经拥有的这些经典工具之一。 第一个版本发布于1976年。无需安装新工具,这反过来又会迫使您安装不使用的编程语言。 实际上,大多数Make都是基于您可能已经知道的Shell脚本构建的。

Another reason is that you will learn something that will be useful in many situations, not just building static websites. That is because while Make usage is for a specific purpose, this purpose is quite generic. You create target tasks and organize the dependencies between them. Here is a dummy example for building a website:

另一个原因是,您将学到在许多情况下有用的知识,而不仅仅是构建静态网站。 这是因为虽然Make使用是出于特定目的,但此目的是相当通用的。 您创建目标任务并组织它们之间的依赖关系。 这是构建网站的虚拟示例:

all: html css


html:
	@echo "Building some HTML..."
css:
	@echo "Building some CSS..."

Here if you put this in a directory in a file called “Makefile” then while inside the directory you could use the command make html or make css. But also you could use the command make all which will build both HTML and CSS because in the specification, what is after the colon on the same line are dependencies. Actually we can even run make on its own because without an argument, Make will defaults to the first target/task it finds in the file.

在这里,如果将其放置在名为“ Makefile”的文件中的目录中,则可以在目录中使用命令make htmlmake css 。 但是您也可以使用命令make all来构建HTML和CSS,因为在规范中,同一行中冒号后面是依赖项。 实际上,我们甚至可以自己运行make ,因为没有参数,Make将默认为其在文件中找到的第一个目标/任务。

Finally, the thing with Make is that it is perfect for rebuilding only what is necessary on each iteration. That is because the way Make works is that for every target, it compares the modification time of the dependencies and target files to know if the target needs to be built or not.

最后,Make的优点在于,它非常适合仅重建每次迭代所需的内容。 这是因为Make的工作方式是,对于每个目标,它都会比较依赖项和目标文件的修改时间,以了解是否需要构建目标。

WARNING: In order for Make to work properly, you need to use tabs for indentation. If you use spaces, it will not work. If you use spaces in your text editor and expand tabs, make sure there is an exception for Makefiles. Here is how you would set that in Vim:

警告:为了使Make正常工作,您需要使用制表符进行缩进。 如果使用空格,将无法使用。 如果在文本编辑器中使用空格并展开选项卡,请确保Makefiles例外。 这是在Vim中设置的方式:

autocmd FileType make setlocal noexpandtab tabstop=4 shiftwidth=4

进行静态网站项目 (Make A Static Website Project)

Let’s get serious now. Feel free to change anything according to your tastes, but what we are gonna do is have 2 directories, one src for our source files, and one build for our generated files or static assets. The build directory is gonna be the finished website.

让我们认真点吧。 可以根据自己的喜好随意更改任何内容,但是我们要做的是有2个目录,一个用于源文件的src ,一个用于生成的文件或静态资产的buildbuild目录将是完成的网站。

So add these directories and a Makefile in which you’re gonna start with the following:

因此,添加这些目录和一个Makefile ,您将在其中以以下内容开始:

SRC_DIR = src
DST_DIR = build

So you see you can create some kind of variables. Note that you can put white space around the equal sign which is not possible in a shell script.

这样您就可以创建某种变量。 请注意,可以在等号周围放置空格,这在Shell脚本中是不可能的。

做一些CSS (Make Some CSS)

We’ve just created placeholders for our 2 main directories: the source and the destination. Now let’s add a few more for building our CSS files. We’ll consider that all our source files are SCSS files, all on the same level. And a nested includes directory for our SCSS includes, the files starting with an underscore. Feel free to simplify the code if you don’t need included files.

我们刚刚为我们的两个主要目录创建了占位符: sourcedestination 。 现在,我们再添加一些内容来构建CSS文件。 我们将认为我们所有的源文件都是SCSS文件,都在同一级别上。 我们的SCSS include的嵌套includes目录包含以下划线开头的文件。 如果不需要包含文件,请随时简化代码。

Here is the structure so far:

这是到目前为止的结构:

./
├── Makefile
├── build/
└── src/
└── scss/
├── includes/
│ └── _inc.scss
└── main.scss

You can obviously have more SCSS files and more includes. Here is our new Makefile:

您显然可以拥有更多的SCSS文件和更多包含文件。 这是我们的新Makefile:

SRC_DIR = src
DST_DIR = buildCSS_DIR = $(DST_DIR)/css
SCSS_DIR = $(SRC_DIR)/scss
SCSS_INCLUDES_DIR = $(SCSS_DIR)/includesSCSS_FILES = $(wildcard $(SCSS_DIR)/*.scss)
CSS_FILES = $(patsubst $(SCSS_DIR)/%.scss, $(CSS_DIR)/%.css, $(SCSS_FILES))

Here you can see how you can create a new variable based on a previous one. The name is just surrounded by $(NAME) . The most complicated part is the 2 final lines. What is between brackets is actually a macro. They can be just a variable name, but you can use functions as well. The wildcard function does the same thing as wildcard in the shell and will basically give you an array of all SCSS files directly inside the SCSS directory. And the patsubst function generates the list of CSS files to create, by substituting the folder name and the extension. It works this way:

在这里,您可以看到如何基于上一个变量创建一个新变量。 名称仅被$( NAME )包围 。 最复杂的部分是最后两行。 括号之间实际上是一个宏。 它们可以只是一个变量名,但是您也可以使用函数。 wildcard功能与外壳中的wildcard具有相同的作用,基本上可以直接在SCSS目录中提供所有SCSS文件的数组。 patsubst函数通过替换文件夹名称和扩展名来生成要创建CSS文件列表。 它是这样工作的:

$( patsubst pattern, replacement, text )

Our text is the list of SCSS files. patsubst applies on each “part” separated by white space (i.e. each file name in this case). And then it creates a new list based on the replacement pattern by matching the placeholder “%” from the original pattern. See the Make manual for more details.

我们的文字是SCSS文件的列表。 patsubst适用于用空格分隔的每个“部分”(在这种情况下,即每个文件名)。 然后,通过匹配原始模式中的占位符“%”,基于替换模式创建一个新列表。 有关更多详细信息,参见制作手册

Now that we have a list of CSS files, we can create our first target:

现在我们有了CSS文件列表,我们可以创建第一个目标:

.PHONY: css
css: $(CSS_FILES) ## Build all CSS files from SCSS

Don’t worry too much about the first line. All you need to know is that most of the time, targets to build are considered files or directories by default. You’ll see this later. But others are just a name for an action. Typical examples are “clean” or “help”. And others — like here — are names representing a group of files. It is not always likely but you may have a file or a directory called “css”, “clean” or “help”. And the problem is that if you run it, it will look for the file or directory and will check the “modification time” to see if it needs to be re-built.

不必太担心第一行。 您需要知道的是,大多数情况下,默认情况下将构建目标视为文件或目录。 您稍后会看到。 但是其他仅仅是行动的名称。 典型示例是“干净”或“帮助”。 其他(如此处)是代表一组文件的名称。 并非总是可能,但是您可能有一个名为“ css”,“ clean”或“ help”的文件或目录。 问题是,如果您运行它,它将查找文件或目录,并检查“修改时间”以查看是否需要重新构建。

What the line with .PHONY does is telling that the target with the specified name is not a file and there is no “modification time” to check. It should always be considered “outdated” and run. Whereas when the target is not .PHONY, Make checks the “modification time” of the files. If one of the dependencies is newer than the target, then the target is re-built because at least one dependency has changed since it was generated.

.PHONY行表示,具有指定名称的目标不是文件,没有“修改时间”要检查。 应始终将其视为“过时”并运行。 而目标不是.PHONY时,Make检查文件的“修改时间”。 如果其中一个依赖关系比目标更新,则重新构建目标,因为自生成以来至少有一个依赖关系已更改。

It is then common to consistently declare .PHONY any target that is not a file to avoid any problem.

然后,通常会始终将.PHONY声明为不是文件的任何目标,以避免出现任何问题。

Then the line of the target itself tells you that you want to create a target called “css” and it has all the CSS files as a dependency. This means that to complete the target, all CSS files must be created. Everything after “#” is just a comment.

然后,目标本身的行会告诉您您要创建一个名为“ css”的目标,它具有所有CSS文件作为依赖项。 这意味着要完成目标,必须创建所有CSS文件。 “#”之后的所有内容仅是注释。

So let’s create a target for these CSS files:

因此,让我们为这些CSS文件创建一个目标:

$(CSS_DIR)/%.css: $(SCSS_DIR)/%.scss $(SCSS_INCLUDES_DIR)/_*.scss
	sass --load-path=$(SCSS_INCLUDES_DIR) --style=compressed --scss $< $@

There is a lot going on here. The first thing to notice is that pattern substitution works for targets as well. Here is how it works:

这里有很多事情。 首先要注意的是,模式替换也适用于目标。 下面是它的工作原理:

# Doing this$(CSS_DIR)/%.css: $(SCSS_DIR)/%.scss# Is the same as doing this for every single 
# CSS file in the directory.$(CSS_DIR)/main.css: $(SCSS_DIR)/main.scss
$(CSS_DIR)/resets.css: $(SCSS_DIR)/resets.scss
$(CSS_DIR)/goodies.css: $(SCSS_DIR)/goodies.scss
# ...

You’re writing many rules/tasks/targets in one single line basically.

您基本上是在一行中编写许多规则/任务/目标。

Then we add the include files as dependencies as well because we don’t know which SCSS files use which include files. So we need to make sure any CSS file is rebuilt each time an include file is modified as well. That is how the target declaration works. You are saying that if any dependency was modified since the target was built, you want to re-build the target.

然后,我们还将包含文件也添加为依赖项,因为我们不知道哪个SCSS文件使用哪个包含文件。 因此,我们需要确保每次修改包含文件时都重新构建任何CSS文件。 这就是目标声明的工作方式。 您说的是,自从构建目标以来,如果修改了任何依赖关系,则要重新构建目标。

Then you have the Sass command itself, the “recipe” for building the target:

然后,您将拥有Sass命令本身,即用于构建目标的“配方”:

sass --load-path=$(SCSS_INCLUDES_DIR) --style=compressed --scss $< $@

In the recipe you can use the macros you already have, but also a few special ones. The macro $@ is a placeholder for the name of the target, useful when declaring targets based on a pattern. And the macro $< is a placeholder for the first dependency in the list. The SCSS file in this case.

在配方中,您可以使用已有的宏,但也可以使用一些特殊的宏。 宏$@是目标名称的占位符,在基于模式声明目标时很有用。 宏$<是列表中第一个依赖项的占位符。 在这种情况下为SCSS文件。

I assume you don’t need explanation for the command line arguments. If you do, you can read the SASS command line manual.

我假设您不需要解释命令行参数。 如果这样做,则可以阅读SASS命令行手册

NOTE: I am using the old Ruby-based command line here. Please note that the new implementation may differ. Read the manual to be sure of the command line arguments if you are using a different one.

注意:我在这里使用旧的基于Ruby的命令行。 请注意,新的实现可能会有所不同。 如果使用其他参数,请阅读手册以确保命令行参数。

All this works fine but it assumes the directory for CSS files already exists. Let’s do something more sophisticated to ensure that the directory is created if it doesn’t exist.

所有这些工作正常,但它假定CSS文件的目录已经存在。 让我们做一些更复杂的事情,以确保如果目录不存在,则创建该目录。

.PHONY: css
css: $(CSS_FILES) ## Build all CSS files from SCSS


$(CSS_DIR):
	mkdir -p $@


$(CSS_DIR)/%.css: $(SCSS_DIR)/%.scss $(SCSS_INCLUDES_DIR)/_*.scss | $(CSS_DIR)
	sass --load-path=$(SCSS_INCLUDES_DIR) --style=compressed --scss $< $@

We create a target for the CSS directory itself. It does not have a dependency because it doesn’t need anything. And we create a new dependency for the CSS files. Now it needs the directory to exist. But this one is after a “|” pipe symbol. Dependencies after a pipe symbol means the dependency only needs to exist. We don’t need to check a “modification time”. I always see this feature used for directories.

我们为CSS目录本身创建一个目标。 它没有依赖性,因为它不需要任何东西。 我们为CSS文件创建了一个新的依赖项。 现在它需要目录存在。 但是这个是在“ |”之后管道符号。 管道符号后的依赖关系意味着依赖关系仅需要存在。 我们不需要检查“修改时间”。 我总是看到此功能用于目录。

Now if you have SCSS files and run make css you should see that it builds the CSS files for you. If you run it a second time without changing any file, Make will tell you everything is up-to-date. Not bad so far.

现在,如果您有SCSS文件并运行make css您应该会看到它为您构建了CSS文件。 如果您第二次运行它而不更改任何文件,Make会告诉您所有内容都是最新的。 到目前为止还不错。

Note that Make will print all commands that it runs. You can add “@” before any command you don’t want to print. Typically you don’t want to print an echo command before running because it would then print twice.

请注意,Make将打印它运行的所有命令。 您可以在不想打印的任何命令之前添加“ @”。 通常,您不希望在运行前打印echo命令,因为它将随后打印两次。

@echo Print only once please

制作一些HTML (Make Some HTML)

I personally often use a simple setup with only one page to build because it is a single-page-application. But for the sake of the example, let’s build many HTML pages with Markdown files instead.

我个人经常使用仅一页构建的简单设置,因为它是单页应用程序。 但是,出于示例的考虑,让我们用Markdown文件构建许多HTML页面。

The process is somewhat similar to what we have done with SCSS files. But there is a major difference: They can be in a nested hierarchy instead of just one level. At least that is what we are building here because it is very likely.

该过程有点类似于我们对SCSS文件所做的操作。 但是有一个主要区别:它们可以处于嵌套的层次结构中,而不只是一个层次。 至少那是我们在这里构建的,因为它很有可能。

Let’s start with our variables at the top:

让我们从顶部的变量开始:

MD_FILES = $(shell find $(SRC_DIR) -type f -name '*.md')
HTML_FILES = $(patsubst $(SRC_DIR)/%.md, $(DST_DIR)/%.html, $(MD_FILES))

We don’t need a sub directory because HTML files go at the root. But we will collect all Markdown files using a new macro function. The shell macro function is pretty simple, it takes a shell command to execute. This one is using the command find to get a list of all the possibly nested Markdown files. The fact that they can be nested is the reason why we don’t use the wildcard function this time, because it does not support recursive wildcards, only the Bourne Shell wildcards.

我们不需要子目录,因为HTML文件位于根目录。 但是,我们将使用新的宏功能收集所有Markdown文件。 shell宏功能非常简单,它需要一个shell命令来执行。 这是使用命令find获取所有可能嵌套的Markdown文件的列表。 它们可以嵌套的事实是我们这次不使用wildcard功能的原因,因为它不支持递归通配符,仅支持Bourne Shell通配符。

And then we get the list of HTML files using the patsubst function like we did for CSS files. Time for some targets:

然后,我们像使用CSS文件一样使用patsubst函数获得HTML文件列表。 一些目标的时间:

.PHONY: html


html: $(HTML_FILES) ## Build all HTML files from Markdown


$(DST_DIR)/%.html: $(SRC_DIR)/%.md
	pandoc --from markdown --to html --standalone $< -o $@

It all seems familiar since the process is the same as for SCSS, except there is no directory to create and we use Pandoc instead of Sass. Note the --standalone option. If you don’t, Pandoc will not create a standalone HTML file with header and body, but a fragment instead.

一切似乎都很熟悉,因为该过程与SCSS相同,除了没有要创建的目录,我们使用Pandoc而不是Sass 。 注意--standalone选项。 如果您不这样做,那么Pandoc不会创建带有标题和正文的独立HTML文件,而是一个片段。

Go ahead and try it. Run make html and it will create your HTML pages.

继续尝试。 运行make html ,它将创建您HTML页面。

Good! Now let’s create a target for building everything. This is quite easy. Another name with its dependencies:

好! 现在,让我们创建一个用于构建所有内容的目标。 这很容易。 具有相关性的另一个名称:

.PHONY: all
all: html css ## Build the whole website

Now you can run make all and it builds everything. I personally put this one as the first target so that I can just run make . If it is not at the top, you still can define it as the default target like this:

现在,您可以运行make all并构建所有内容。 我个人将此作为第一个目标,以便我可以运行make 。 如果不在顶部,则仍可以将其定义为默认目标,如下所示:

.DEFAULT_GOAL := all

使其干净 (Make It Clean)

Now is time to introduce a classic Make target for deleting all generated files and start fresh:

现在该介绍经典的Make目标,以删除所有生成的文件并重新开始:

.PHONY: clean
clean:
	rm $(HTML_FILES)
	rm -rf $(CSS_DIR)

It just deletes all HTML files and the whole CSS directory. You typically use this when something went wrong or in general whenever you want to make sure everything will be re-built next time you run make.

它只是删除所有HTML文件和整个CSS目录。 通常,在出现问题时通常使用此方法,或者通常在需要确保下次运行make时将重新构建所有内容时make

充分利用Pandoc (Make The Best Out Of Pandoc)

OK we have HTML files but we are not using Pandoc to its full potential. You want to create web pages with header, footer and everything. Let’s modify it and take advantage of a few Pandoc features:

好的,我们有HTML文件,但我们并未充分利用Pandoc。 您要创建包含页眉,页脚和所有内容的网页。 让我们对其进行修改,并利用Pandoc的一些功能:

TEMPLATE = $(SRC_DIR)/template.html


$(DST_DIR)/%.html: $(SRC_DIR)/%.md $(TEMPLATE)
	pandoc \
	--from markdown_github+smart+yaml_metadata_block+auto_identifiers \
	--to html \
	--template $(TEMPLATE) \
	-o $@ $<

So we’ve added a template.html file in our sources. That way you can follow the pattern you may have used on dynamic websites. That is to say, have a template for what appears on every single page and includes your Markdown content between the header and the footer.

因此,我们在源代码中添加了template.html文件。 这样,您可以遵循动态网站上可能使用的模式。 也就是说,有一个模板可以显示在每个页面上,并在页眉和页脚之间包含Markdown内容。

In order to do this, we use the template language of Pandoc. At the very least you will use the $body$ which will include the body of your Markdown file. Please note that we’ve removed the --standalone option since we are using a template instead.

为此,我们使用Pandoc的模板语言。 至少您将使用$body$ ,其中包括Markdown文件的正文。 请注意,因为我们使用的是模板,所以我们删除了--standalone选项。

If you need more variables, you can do so in many ways depending what you want to do. If it is build specific or global you can pass it in the command line with options like --variable today="$(date)" . But if your variables are specific to the Markdown file, like the title of the page, you can use metadata.

如果需要更多变量,则可以根据需要执行多种操作。 如果它是特定于构建的或全局的,则可以在命令行中使用--variable today="$(date)"类的选项来传递它。 但是,如果您的变量特定于Markdown文件,例如页面标题,则可以使用元数据。

Indeed if you look at the --from option, instead of just being “markdown”, now it is a longer option with additional features. First of all it uses the github flavored Markdown. But there is also the yaml_metadata_block which lets you include a YAML metadata block, most likely at the top of the Markdown page.

确实,如果您查看--from选项,而不仅仅是“ markdown”,那么它现在是带有其他功能的更长选项。 首先,它使用github风格的Markdown。 但是,还有yaml_metadata_block ,它使您可以包括YAML元数据块,最有可能在Markdown页面的顶部。

---
title: The Practice of Programming
authors:
- Kernighan
- Pike
---

And then all these will be available in your template. We could go a lot further, have multiple templates or includes, etc. But I trust this is enough to get you started and tweak this boilerplate to fit your needs.

然后,所有这些都将在您的模板中可用。 我们可以走得更远,可以有多个模板或包含等。但是我相信这足以使您入门并调整样板以适应您的需求。

For more details, you can read the Pandoc manual.

有关更多详细信息,您可以阅读Pandoc手册

制作一些站点地图 (Make Some Sitemap)

Again there are many things you can add or improve, but an obvious feature would be to create a “sitemap.xml” file, and also a “robots.txt” file. Let’s start by adding a new variable at the top for setting our domain name.

同样,您可以添加或改进许多内容,但是一个明显的功能是创建“ sitemap.xml”文件和“ robots.txt”文件。 首先,在顶部添加一个用于设置域名的新变量。

BASE_URL = "https://www.example.org"

And then we want to make sure these files are built when building the “all” target. In other words we will add them as dependencies

然后,我们要确保在构建“全部”目标时已构建这些文件。 换句话说,我们将它们添加为依赖项

all: html css $(DST_DIR)/robots.txt $(DST_DIR)/sitemap.xml
$(DST_DIR)/robots.txt:
	@echo "User-agent: *" > $@
	@echo "Allow: *" >> $@
	@echo "Sitemap: $(BASE_URL)/sitemap.xml" >> $@


$(DST_DIR)/sitemap.xml: $(HTML_FILES)
	@echo '<?xml version="1.0" encoding="UTF-8"?><urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">' > $@
	for f in $^; do \
		@echo "<url><loc>$(BASE_URL)$${f#$(DST_DIR)}<loc></url>" >> $@
	done
	@echo '</urlset>' >> $@

The robots target should not be too hard to understand. We’re just using a few “echo” commands to write the file. We’re using the BASE_URL variable to add your domain name.

机器人目标不应太难理解。 我们只是使用一些“ echo”命令来写入文件。 我们正在使用BASE_URL变量添加您的域名。

The sitemap is a little bit more complicated. Inside the opening and closing urlset tag, we are iterating through all the html files and add a url tag. Again we put our domain name contained in the BASE_URL variable, but the problem is that our html files have the build/destination directory name in them that we need to remove.

该站点地图稍微复杂一点。 在打开和关闭urlset标记内,我们遍历所有html文件并添加url标记。 同样,我们将域名包含在BASE_URL变量中,但是问题是我们的html文件中包含需要删除的build / destination目录名。

First of all, note that both make macros and bash variables start with “$”. In order to do this, you have to use a double dollar sign instead “$$” so that make knows it is not a macro. Then what is inside curly brackets is just the normal bash way to remove a prefix. But here the prefix is a make macro/variable. Phew…Have you seen the movie “Inception”?

首先,请注意make宏和bash变量均以“ $”开头。 为此,您必须使用双美元符号而不是“ $$”,以便使人知道它不是宏。 那么花括号内的内容只是删除前缀的常规bash方法。 但是这里的前缀是make宏/变量。 ew ...您看过电影《盗梦空间》吗?

使其自我记录 (Make It Self Documenting)

Just as a bonus, here is a classic target for getting a summary of all the targets you want to call from the command line.

作为奖励,这是一个经典目标,用于汇总您要从命令行调用的所有目标。

.PHONY: help


help: ## Show this help                        
	@egrep -h '\s##\s' $(MAKEFILE_LIST) | \                         
	awk 'BEGIN {FS = ":.*?## "}; {printf "\033[34m%-15s\033[0m %s\n", $$1, $$2}'

It simply scans your Makefile(s) for lines with a double sharp sign “##”, which is why all comments after our targets have 2 sharps instead of 1 for a normal command. Then it extracts the name and the comment to display it nicely when you run make help.

它仅扫描您的Makefile中是否有双尖锐符号“ ##”的行,这就是为什么我们目标之后的所有注释都具有2尖锐而不是正常命令为1的原因。 然后,它会提取名称和注释,以便在运行make help时将其很好地显示。

I did not come up with this. It is a neat trick you’ll find all over the internet.

我没有想到这一点。 您可以在互联网上找到一个绝妙的技巧。

完成它 (Make It Complete)

Here is a Gist of the whole Makefile for reference:

这是整个Makefile的要点供参考:

SRC_DIR = src
DST_DIR = build


CSS_DIR = $(DST_DIR)/css
SCSS_DIR = $(SRC_DIR)/scss
SCSS_INCLUDES_DIR = $(SCSS_DIR)/includes


SCSS_FILES = $(wildcard $(SCSS_DIR)/*.scss)
CSS_FILES=$(patsubst $(SCSS_DIR)/%.scss, $(CSS_DIR)/%.css, $(SCSS_FILES))


MD_FILES = $(shell find $(SRC_DIR) -type f -name '*.md')
HTML_FILES = $(patsubst $(SRC_DIR)/%.md, $(DST_DIR)/%.html, $(MD_FILES))
TEMPLATE = $(SRC_DIR)/template.html


BASE_URL = "https://www.example.org"


.PHONY: all
all: html css $(DST_DIR)/robots.txt $(DST_DIR)/sitemap.xml ## Build the whole website


#
# HTML
#


.PHONY: html
html: $(HTML_FILES) ## Build all HTML files from SLIM files (even nested)


$(DST_DIR)/%.html: $(SRC_DIR)/%.md
	pandoc --from markdown --to html --standalone $< -o $@


$(DST_DIR)/%.html: $(SRC_DIR)/%.md $(TEMPLATE)
	pandoc \
	--from markdown_github+smart+yaml_metadata_block+auto_identifiers \
	--to html \
	--template $(TEMPLATE) \
	-o $@ $<


#
# CSS
#


.PHONY: css
css: $(CSS_FILES) ## Build all CSS files from SCSS


$(CSS_DIR):
	mkdir -p $@
	
$(CSS_DIR)/%.css: $(SCSS_DIR)/%.scss $(SCSS_INCLUDES_DIR)/_*.scss | $(CSS_DIR)
	sass --load-path=$(SCSS_INCLUDES_DIR) --style=compressed --scss $< $@


#
# Robots.txt
#


$(DST_DIR)/robots.txt:
	@echo "User-agent: *" > $@
	@echo "Allow: *" >> $@
	@echo "Sitemap: $(BASE_URL)/sitemap.xml" >> $@


#
# Sitemap.xml
#


$(DST_DIR)/sitemap.xml: $(HTML_FILES)
	@echo '<?xml version="1.0" encoding="UTF-8"?><urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">' > $@
	for f in $^; do \
		@echo "<url><loc>$(BASE_URL)$${f#$(DST_DIR)}<loc></url>" >> $@
	done
	@echo '</urlset>' >> $@


#
# Helpers
#


.PHONY: clean
clean:
	rm $(HTML_FILES)
	rm -rf $(CSS_DIR)
	
.PHONY: help
help: ## Show this help
	@egrep -h '\s##\s' $(MAKEFILE_LIST) | \
	awk 'BEGIN {FS = ":.*?## "}; {printf "\033[34m%-15s\033[0m %s\n", $$1, $$2}'

翻译自: https://itnext.io/glorious-makefile-building-your-static-website-4e7cdc32d985

makefile静态编译

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值