After getting used to writing build commands using SRC in package.json, I saw that there was a Makefile in the element-UI repository. So I googled it, and I saw how powerful this thing is.
A Makefile is a C/C++ tool that was originally used in UNIX as an engineering tool to perform a series of compilation and concatenation operations through the make command. If there is a Makefile in a directory that has a make environment. Typing make will execute one of the target commands in the Makefile.
I metMakefile
Use the Element-UI Makefile directly as an example.
.PHONY: dist test
default: help
install:
npm install
new:
node build/bin/new.js $(filter-out $@,$(MAKECMDGOALS))
deploy:
@npm run deploy
help:
@echo "\033[35mmake\033[0m \033[1m Command Instructions \033[0m"
Copy the code
On a MAC, you can run the make command directly. Windows Download the GUN tool of make
If you already have make installed globally on your computer, when you clone the element code and execute make install in the root directory, it will have the same effect as NPM install. Take a look at what make Install does.
- perform
make
Command to find it in this directoryMakefile
File. - find
Makefile
File corresponding to the command line parameterinstall
The goal of. The goal here is thatinstall:
- perform
npm install
The following statement.npm run dev
Makefile
The file format
The make command itself is not difficult; it simply executes the target that follows. The target details are in the Makefile.
A Makefile is made up of a series of rules, and each rule needs to know two things: what the build goal is, and how to build it. Each rule follows the following format:
<target> : <prerequisites>
[tab] <commands>
Copy the code
The first line is:
It’s divided into two parts.
- The first part is the target
target
That is to performmake target
Command to match the target. - The latter part is the precondition (dependent target), if the first line is written as
target1: target2 target3
, then in executionmake target1
“, you need to execute the command firstmake target2
make target3
It’s executed at the endtarget1
The followingcommonds
Statements.
The second row must consist of onetab
Key, followed by the statement that needs to be executed
Target for each rule is required, both Prerequisites and the second line are optional, but there must be at least one in between.
This is just enough for the Makefile code in the Element-UI project to make sense of most of it. But if you look at the first line of the code, PHONY: dist test, what is that?
Target and Phony Target
Each rule contains a target, which in make is usually a file name that identifies the object that the rule needs to build. The destination can be one or more file names separated by Spaces.
Of course, the name of a target can also be the name of a specific operation, which is called a phony target. For example, remove below is a pseudo target. His role is to delete files.
remove:
rm *.js
Copy the code
However, if make remove is executed again and there is a file named remove in the directory, the command will not be executed because make finds that the file already exists and there is no need to rebuild it, it will ignore the command.
To avoid this, you can proactively declare remove as a pseudo target.
.PHONY: remove
remove:
rm *.js
Copy the code
When.PHONY: actively declares remove to be a PHONY target, make does not check for the existence of files that contain remove, but instead executes the remove command every time. You can also see that.phony: dist test is declared in the first line of the Makefile in the Element project, again to prevent the command from being executed because the file name already exists in the directory.
Echo @
In a Makefile, # denotes a comment.
test:
# This is a comment
touch a.js
Copy the code
When make test is executed, a comment is printed and the a.js file is created.
When preceded by an @, the echo is turned off. (Since echo is also equivalent to typing an echo, it is common to precede both comments and echo with @.)
test:
@# This is a test
@echo some
Copy the code
In Element, if the make new some project generates a new component, let’s analyze node build/bin/new.js $(filter-out $@,$(MAKECMDGOALS)). Let’s see what we know about make.
variable
Makefiles allow variables to be customized with an equal sign and called with $().
txt = hello world
test:
@echo $(txt)
Copy the code
Automatic variables$@
The Make command also provides automatic variables whose values are relevant to the current rule.
$@ refers to the current target, which is matched by the make command. For example, when we make foo, $@ is foo
This variable is used to abbreviate the current target:
a.js b.js c.js:
touch $@
Copy the code
Special variablesMAKECMDGOALS
When make executes, it sets a special variable, MAKECMDGOALS, that keeps track of the list of targets specified by the command-line arguments. That is, using this variable, we can get arguments from the command line.
create:
@echo $(MAKECMDGOALS)
Copy the code
Executing the make create newCom command will print the create newCom fields.
function
Make can also use functions in the following format:
$(function arguments)
# or
${function arguments}
Copy the code
filter-out
Inverse filter function
Filter out all content with pattert in objs in the format:
$(filter-out pattert, objs)
objs = aa bb cc dd ee
pattert = bb cc ee
out:
@echo $(filter-out $(pattert), $(objs))
Copy the code
Run make out to print aa DD
node build/bin/new.js $(filter-out $@,$(MAKECMDGOALS))
Either executing make new some or making new-lang some logic in Element passes a parameter to a script file. This command first uses Node to run the build/bin/new.js file and then uses the filter-out function to remove the current target from the arguments on the command line.
We can create a new build/bin/new.js file, write the following code, and look at the input.
<! -- build/bin/new.js --> console.log(process.argv)Copy the code
Makefile
new:
node build/bin/new.js $(filter-out $@, $(MAKECMDGOALS))
Copy the code
Run the make new testCom command.
[ 'C:\\Program Files\\nodejs\\node.exe'.'C:\\Users\\***\\Desktop\\***\\a.js'.'testCom' ]
Copy the code
In new.js we can use process.argv[2] to get command-line arguments for further scripting.