background

In a company project, do you still add content to the page with new page => every time you encounter a new requirement, such as vUE template => add route? Doesn’t it bother you? If so, try an automated build. It smells good

How is the automatic build of Element-UI done

In open source projects, especially UI library development, there are too many people working together, and everyone’s code habits are different. And each component in the UI library will also involve multilingual, unit tests, routing, component readme.md documents and other files. So it would be too cumbersome to create these slowly each time, and multiple people modifying common files such as routing files would cause too many conflicts. So in open source projects there are a lot of scripts to automate the generation of certain files.

makefile

There is a makefile at the root of the Element-UI project, where the purpose of each command is commented out. Windows users need to download scripts to execute with the make command. MAC users don’t.

@The default # comment is printed in the log, but the @# comment is not
@Does ignoring checks in the script commands below conflict with the dist and test directories, meaning the commands will be executed anyway
.PHONY: dist test 

@The help script is executed by default
default: help

@NPM run build:theme 'NPM run build:theme'
@# : the command is preceded by the colon, and the second line after the colon should start with a TAB, followed by the command
@TAB + NPM NPM build: theme
# build all theme
@# The build theme comment above can be viewed in the screenshot below, which will be output in the log
build-theme: 
	npm run build:theme
install:
	npm install
dev:
	npm run dev
@# $() is the use function
@# $@ is the current command itself such as 'make new', where $@ is new
@The # MAKECMDGOALS special variable keeps track of the list of targets specified by the command line arguments, meaning that using this variable, we can get the command line arguments
@# For example, when we create a new component, the script 'make new Wailen' MAKECMDGOALS equals wailen
@# filter-out Filter out $(MAKECMDGOALS)
@Create a new component and pass in the component name. The component name must not be new. If the component name is new, you can see the screenshot below
new:
	node build/bin/new.js $(filter-out $@.$(MAKECMDGOALS))
@# omit some scripts, interested can check the source code
help:
	@echo "\033[35mmake\033[0m \033[1m Command Instructions \033[0m"
	@echo "\033[35mmake install\033[0m\t\033[0m\t\033[0m\t\033[0m\t \033[0m\t\033] -- Install dependency"
	@echo "\033[35mmake new 
      
        [中文名]\033[0m\t-- create new component package. E.g. 'make new button '"
      
	@echo "\ [033 35 mmake dev \ [0 033 m 033 [0 m \ \ t \ \ t 033 [0 m \ t \ [0 m \ t - 033 development mode"
	@echo "\033[35mmake dist\033[0m\t\033[0m\t\033[0m\t\033[0m\t \033[0m\t\033[0m\t\033[0m\t\033[0m\t \
	@echo "\033[35mmake deploy\033[0m\t\033[0m\t\033[0m\t\033[0m\t \033[0m\t- deploy demo"
	@echo "\033[35mmake pub\033[0m\t\033[0m\t\033[0m\t\033[0m\t \033[0m\t\033[0m\t\033[0m\t\033] -- post to NPM"
	@echo "\033[35mmake new-lang 
      
       \033[0m\t\033[0m\t\033[0m\t \033[0m\t\033[0m\t\033[0m\t \t-- Add new language for website. For example, 'make new-lang fr'"
      

Copy the code

#Note the output Filter the new keyword. If the new parameter is passed in, filter it out

Of course, if you don’t want to execute the Node script directly with make, for example, make new component name is the same as node build/bin/new.js component name

new.js

New.js is the core file for automation. Let’s start by thinking that creating a component file is nothing more than a two-step process

  • Create a file
  • Add content

file-save

The file-save package is used primarily to create files and add content. Let’s start with the API

const fileSave = require('file-save');
const content = "const fs = require('fs');"
const callback = () = > { console.log('Script execution') }
fileSave('File path')
   .write('File contents like the content above'.'utf8', callback) // Successful writing triggers a callback
   .write('Continue adding content'.'utf8')
   .end('\n') // The file operation ends with a blank line
Copy the code

The following files are generated

More documentation can be found at file-Save

In element-UI, a Files array object is used to manage the filename and code content to be created.

This will create the corresponding file directly through the loop Files.

/ / create a package
// Directory generated by the component
const PackagePath = path.resolve(__dirname, '.. /.. /packages', componentname);
Files.forEach(file= > {
  fileSave(path.join(PackagePath, file.filename))
    .write(file.content, 'utf8')
    .end('\n');
});
Copy the code

Changes to reference resource files

In addition, it is common to create components and modify corresponding references to components, such as routing configuration files. We can also add the corresponding route through file-save. File-save itself overwrites the contents of the previous file, that is, deletes it and regenerates it. So if the operation is to add on the original basis, you need to get the content of the original file, and then splice the new content on this basis. We can do this:

const fileSave = require('file-save');
const fs = require('fs');

const content = `const fileSave = require('file-save'); `
const oldCode = fs.readFileSync('./demo.js')
fileSave('demo.js')
  .write(oldCode+content, 'utf8')
  .end('\n')
Copy the code

That is, through the FS module to read the old content of the file, and then can be spliced. Here’s what Element-UI does:

fs.createWriteStream

The file-save principle is encapsulated by the Fs.createWritestream API. A little bit about how to use it

const fs = require('fs')

// Create an object of the Writable fs.WriteStream class that inherits from 
      
const writer = fs.createWriteStream('createStream.js', { // Find the file, create it if not
    // The default value is w. When you call writer.write, all the contents of the file will be overwritten.
    // Delete all previous contents of the file and write new data
    flags: 'w'
})


// Write data to the stream
writer.write('New contents of this file')
Copy the code

The source content of file-save can be viewed in the pseudo-code below.

const savefs = {}
savefs._create_dir = function (fp, opts) {
  mkdirp.sync(fp, opts);
}
savefs.wstream = function (file) {
  var ws = fs.createWriteStream(file);
  this.writer = ws;
  return this;
}
savefs.write = function(chunk, encoding, cb) {... } savefs.end =function(chunk, encoding, cb) {... } savefs.finish =function(cb) {... } savefs.error =function(cb) {... }export { savefs }
Copy the code

We can create files using node’s fs.writeFile API.

fs.writeFile('File path'.'What to write'['coding'].'Callback function');
Copy the code

You can see that the parameter is the same as file-save

conclusion

In the end, an automated creation component is nothing more than two core creation files to add content to. The file-save package can achieve these two operations, and then we can combine our own business, configure the path and content of the generated file, as well as modify some public files to the new file resource reference. Node scripting is much more interesting than writing back-end scripts

The last

Interested in source partners can also join the source code reading activities of the Ruochuan organization

reference

file-save

Copy and paste every new page? More than 100 lines of source code add element UI component features to help you reduce rework

The Camelcase principle is to convert a string into a hump using some regulars

Make automates build analysis in Element-UI