Develop scaffolding and encapsulate automated build workflows
Engineering Overview
Definition of engineering and main problems to be solved
-
Fully armed: Improve combat effectiveness through engineering.
-
Problem 1: You want to use the new ES6+ features, but have compatibility problems.
-
Problem 2: You want to use Less/Sass/PostCSS to enhance the programmability of CSS but the runtime environment does not support it directly.
-
Problem 3: You want to use a modular approach to improve project maintainability but the runtime environment does not directly support it.
-
Problem 4: Code and resource files need to be manually compressed before deployment.
-
Problem 5: The deployment process requires manual uploading of code to the server.
-
Problem 6: When developing in collaboration, you can’t rigidly agree on everyone’s code style.
-
Problem 7: The quality of code pulled back from the repository is not guaranteed.
-
Problem 8: Some functions need to wait for the back-end service interface to be completed in advance.
-
Question classification
- Disadvantages of traditional language or grammar.
- Modularity/componentization cannot be used.
- Repetitive mechanical work.
- Uniform code style, quality assurance.
- Depends on back-end service interface support.
- Overall reliance on back-end projects.
The performance of engineering during a project.
-
All the means to reduce cost and increase efficiency, quality assurance for the purpose of all belong to engineering ☚
-
All repetitive tasks should be automated.
-
Create a project
- Create the project structure.
- Create a specific type of file.
-
coding
- Formatting code
- Checking code Style
- Compile/build/package
-
Preview/Test
- Web Server/Mock
- Live Reloading/HMR
- Source Map
-
submit
- Git Hooks
- Lint-staged
- Continuous integration
-
The deployment of
- CI/CD
- Automatic release
-
Engineering ≠ a tool
- Tools are not the core of engineering
- The core of engineering is the overall planning or architecture of the project
- Tools are simply a means of landing a planning or architectural process.
Engineering with Node.js
-
Project Powered by Node.js
-
Node.js gives the front end a new stage.
-
Front-end engineering is strongly driven by Node.js.
-
Implement engineering
- Scaffolding tool development
- Automated construction system
- Modular packaging
- Project code normalization
- Automated deployment
Scaffolding tool
The role of scaffolding
-
Originator of front-end engineering
-
Used to create the project infrastructure
-
Provide project specifications and conventions
- Same file organization structure
- Same development paradigm
- Same module dependencies
- Same tool configuration
- Same basic code
-
You can quickly build a skeleton of a specific type of project
-
Example: The IDE project creation process is a scaffolding workflow.
-
The front-end scaffolding is a separate tool.
-
Goal: To solve the complexity of our project creation process.
Commonly used scaffolding tools
-
Scaffolding tools used to create projects
-
Scaffolding tools that serve a particular type of project
- The React project ↝ create – React – app
- Vue. Js project ↝ Vue – cli
- Agular project ↝ presents – the cli
- Common ground: Generate project infrastructure based on the information you provide.
- The difference: Generally only applies to projects within the framework they serve.
-
General purpose project scaffolding tool
- Represented by Yeomen.
- You can generate a corresponding project structure from a set of templates.
- Very flexible
- It’s easy to expand
-
-
Scaffolding of another kind
- Used to create certain types of files during project development
- This is represented by Plop
- Example: files needed to create a component/module.
-
Focus on a few representative tools
- Yeoman
- Plop
-
How scaffolding works
- Once started, some preset questions are asked, and the answers are combined with some template files to generate the project structure.
- Scaffolding is essentially a Node CLI application.
General purpose scaffold tool analysis
Yeoman
- The Web's scaffolding tool for modern Webapps - As The oldest, most powerful and versatile tool, we could use a lot of scaffolding for modern webapps. - More like a scaffolding platform - Official definition: a scaffolding tool for creating modern Web applications. - You can use generators to create any type of project. - Cons: Yeoman is considered too generic and unfocused by many framework-focused folks. They prefer to use tools like VUe-CLI. - Basic use - Dependent Node environment - YARN Global add YO - With Generator: YARN global add generator-node - New project use: Yo node - Summary - Install yo - NPM install yo -- global-yarn global add yo - Install the corresponding generator- NPM install generator-node -- global-yarn global add generator-node - Run generator-cd path/to/ project-dir-mkdir my-module-yo node-sub with yo Generator - Sub-level Generator - uses: Yo node: CLI - General use step -1, identify your requirements - 2, find the appropriate generator-3, install the generator-4 found globally, run the corresponding generator-5 from Yo, interoperate with the command line option -6, Generate the project structure you need - Example: Web application generator YARN Global Add Generator - WebApp Yo webApp - Custom Generator - Build your own scaffolding based on Yeoman. - Create a Generator module - The Generator is essentially an NPM module. - the Generator structure - the Generator/app/index, js - Generator/component/index. The js - package. Json - named: Generator -<name> - Case demonstration - mkdir generator-sample - CD generator-sample - yarn init - Initialize package.json file - yarn add Yeoman -generator -vscode Open: code. -Create file: Generator /app/index.js - this file is the core entry for Generator - needs to export a type inherited from Yeoman Generator - Yeoman Generator Some of the lifecycle methods we defined in this type are automatically invoked at work. - We can implement some functions in these methods by calling some of the utility methods provided by the parent class, such as file writing.Copy the code
- const Generator = require('yeoman-generator')
- module.exports = class extends Generator {
writing () {
// Yeoman automatically calls this method during file generation
// We are trying to write files to the project directory
this.fs.write(this.destinationPath('temp.txt'), Math.random().toString())
}
}
- yarn link
Copy the code
- cd .. -mkdir my-proj -cd my-proj -yo sample -create file from template -create template file: App /templates/foo. TXT - Templates follow the EJS template syntax - <%= name %> - <% if(success) {%> Generate file content <%} %> - Write files to target by template - Template file path: Const temp1= this.templatepath ('foo.txt') - Output target path: const output= this.destinationPath('foo') - template data context: Const context = {name: 'SJZ'} -this.fs.copytpl (temp1, output, context) -Yo sample - The template method is much more efficient than manually creating each file. - Module. Exports = class extends Generator {only selected by targets () {// Yeoman will automatically invoke this method when interrogating the user. // In this method, you can invoke the parent class prompt() method to issue a command line query to the user. return this.prompt([ { type:'input', name: 'name', message: 'sjz', default: This.appname}]). Then (answers ⥤ {console.log(answers) this.answers = answers})}Copy the code
}
Copy the code
- Vue Generator case - mkdir Generator - SJZ - vue-cd Generator - SJZ - vue-yarn init - yarn add yeoman- Generator - code. - Create main entry file: generator/app/index.js - const Generator = require('yeoman-generator') - module.exports = class extends Generator { prompting () { return this.prompt([ { type: 'input', name: 'name', message: 'your project name', default: This.appname}]). Then (answers ⥤ {this.answers = answers})} writing () {const templates = [] Templates. ForEach (item ⥤ {// item ⥤ each file path this.fs.copyTpl(this.templatepath (item), this.destinationPath(item), this.answers ) }) }Copy the code
} - Create the templates directory and copy the prepared files and directory structure into the templates directory. - yarn linkCopy the code
- cd .. -mkdir my-proj -cd my-proj-yo sjz-vue -publish Generator -host the project source code to a public source code repository. Git status - git add. - git commit -m "feat: Git push -u origin master - NPM publish/yarn publish - yarn The publish - registry=https://registry.yarnpkg.com - question: mirror, taobao is a read-only imageCopy the code
Plop
- A nice little scaffolding tool - is a small tool for creating specific types of files in a project, similar to the Sub Generator in Yeoman. - Generally not used independently - generally integrated into the project to automate the creation of the same type of files - Usage scenarios: The same type of files must be created repeatedly. For example, three files (CSS, js, and HTML) must be created to create components in react. New plopfile.js file - entry file for plop work - need to export a function - object parameters that receive a plop in the function - parameter plop object provides a series of utility functions - these utility functions are used to create generator tasks. On the code -Copy the code
module.exports = plop ⥤ {
plop.setGenerator('generatorName', {
description: 'Generator description'.prompts: [{type: 'input'.name: 'name'.message: 'Screen prompt'.default: 'Default answer',}],actions: [{type: 'add'.// Add a brand new file
path: 'src/components/{{name}}/{{name}}.js'.templateFile: 'plop-templates/component.hbs'}, {type: 'add'.// Add a brand new file
path: 'src/components/{{name}}/{{name}}.css'.templateFile: 'plop-templates/component.css.hbs'}, {type: 'add'.// Add a brand new file
path: 'src/components/{{name}}/{{name}}.test'.templateFile: 'plop-templates/component.test.hbs',},]})}Copy the code
- Run - YARN plop generatorName - summary - 1, install plop module as project development dependency - 2, create plopfile.js file - 3 in project root directory, define scaffolding task - 4 in plopfile.js file, Write a template for generating a specific type of file - 5 that runs the scaffolding task through the CLI provided by PLOpCopy the code
Develop a scaffold
-
mkdir sample-scaffolding
-
cd sample-scaffolding
-
yarn init
- Initialize the package.json file.
-
VsCode opens: code.
-
Add the bin property to package.json
- The value of ‘cli. Js’
-
Root directory to create a new file: cli.js
-
This file must have a specific header: #! /usr/bin/env node
-
Under the Linux/macOS systems
- You also need to change the read and write permission on this file to 755
- In particular, chmod 755 cli.js is used to achieve the modification
-
-
Contents: the console. The log (‘ SJZ)
-
-
yarn link
- Link scaffolding to global
-
Then you can do it from the command line: sample-scaffolding
- Running result: SJZ
-
The specific process of implementing scaffolding
-
1. Ask the user questions through command line interaction
-
Install the query module Inquirer
- yarn add inquirer
-
-
2. Generate files according to the results of user answers
-
Cli.js code implementation
-
- const fs = require('fs')
const path = require('path')
const inquirer = require('inquirer')
const ejs = require('ejs')
-
- inquirer.prompt([
{
type: 'input'.name: 'name'.message: 'Project name? ',}]). Then (answers ⥤ {// Generate a file based on the user's answer
// Template directory
const tmplDir = path.join(__dirname, 'templates')
// Target directory
const destDir = process.cwd()
// Convert all files under the template to the target directoryFs.readdir (tmplDir, (err, files) ⥤ {if(err) throwErr files. ForEach (file ⥤ {// Render files through the template engineEjs. renderFile(path.join(tmplDir,file), answers, (err, result) ⥤ {if(err) throw err
fs.writeFileSync(path.join(destDir, file), result)
})
})
}
})
Copy the code
- Create template file - templates/index.html - templates/style. CSS - Install the template engine - yarn add EJsCopy the code
Automated build
Introduction to the
-
All repetitive tasks should be automated
-
Name to explain
-
automation
- Machines do some of the work instead of hand
-
build
- You can think of it as transformation
- To convert one thing into something else.
-
-
The automated construction or conversion of source code to production code
- This transformation or build process is called an automated build workflow.
-
role
-
You can get rid of problems caused by runtime environment compatibility
-
Allow efficient syntax, specifications, and standards
-
ECMAScript Next
-
Sass
-
A template engine
- Abstract duplicate code in source files
-
Most of these uses are not directly supported by browsers
-
☞ features that are not supported can be built to transform using an automated build tool.
-
-
Can improve development efficiency
-
First experience with automated builds
-
Create a new Sass file: SCSS /main.scss
-
content
- $body-bg: #f8f9fb
-
$body-color: #333
body { margin: 0 auto; padding: 20px; max-width: 800px; Background – color: body – bg. color:body-bg; Color: the body – bg. color:body-color; }
-
yarn add sass –dev
-
Run./node_modules/. Bin /sass SCSS /main. SCSS CSS /style.css
- style.css
- style.css.map
-
NPM Scripts
-
Wrap build command
-
Add scripts configuration to package.json
- “scripts”: {
“Build “: “sass SCSS /main.scss CSS /style.css –watch”, // “preserve”: “yarn build”, // NPM Scripts hook mechanism “serve”: “browser-sync . –files “css/*.css””, “start”: “run-p build serve”,
-
}
- yarn build - yarn serve-yarn start - The simplest way to automate the build workflow - yarn add browser-sync --dev - Used to start a test server to run the project. - yarn add NPM -run-all --dev - Run multiple tasks at the same time.Copy the code
Common automated build tools
Grunt
- Introduction - The first front-end build system - the plugin ecosystem is perfect - plug-ins can automate almost anything you want. - Disadvantages - The working process is implemented based on temporary files, so the build speed is correspondingly slow. - For example, to complete the sass file construction - first do the sass file compilation operation - then automatically add some private attributes prefix. - Then compress the code - Grunt has disk operations at each step of the process. - Basic use - initialize package.json file - yarn init --yes - Add grunt module - yarn add grunt - Add gruntfile.js file - code gruntfile.js - Grunt entry file - used to define tasks that need to be performed automatically by Grunt - needs to export a function that takes a Grunt parameter - Grunt is an object that provides some API for creating tasks - codeCopy the code
- module.exports = grunt ⥤ {grunt. RegisterTask ('taskName', () ⥤ {
console.log('sjz')
})
grunt.registerTask('taskName1'.'Task Description', () ⥤ {
console.log('sjz515')})// grunt. RegisterTask ('default', 'default task description ', () ⥤ {
// console.log('sjz515')
// })
grunt.registerTask('default'['taskName'.'taskName1'])
grunt.registerTask('async-task', () ⥤ {
setTimeout(() ⥤ {console.log('sjz515')},1000)
})
grunt.registerTask('async-task1'.function () {
const done = this.async()
setTimeout(() ⥤ {console.log('sjz515')
done()
}, 1000)})}Copy the code
- yarn grunt taskName - yarn grunt taskName1 - yarn grunt - The default task does not need to be specified. - yarn grunt async-task-grunt Supports synchronization mode by default Description Console. log is not executed in the asynchronous task. Exports = grunt ⥤ {grunt. RegisterTask ('bad', 'yarn grunt async-task1 - Can be successfully executed - Flag task failed - module.exports = grunt ⥤ {grunt. () ⥤ {console.log(' SJZ ') return false}) grunt. RegisterTask ('async-task1', Function () {const done = this.async() setTimeout(()⥤{console.log('sjz515') done(false)}, 1000)})Copy the code
}
- If a task fails, subsequent tasks will not be executed. - You can specify the --force parameter to control whether a task fails to be executed. Exports = Grunt ⥤ {Grunt. InitConfig ({taskName: 'SJZ ', foo: {bar: 'SJZ'}}) grunt. RegisterTask ('taskName', () ⥤ {console.log(grunt. Config ('taskName'))}) grunt. () ⥤ {console.log(grunt. Config ('foo.bar'))})Copy the code
}
- yarn grunt taskName - yarn grunt foo - grunt Multi-target task - In multi-target mode, a task can be configured to form multiple sub-tasks. -module.exports = grunt ⥤ {grunt. InitConfig ({build: {options: {foo: 'bar'}, CSS: {options: {foo: 'baz'}}, js: '2' } }) grunt.registerMultiTask('build', function() { console.log('multi task~') console.log(`target: ${this.target}, data:${this.data}, options: ${this.options()}`) })Copy the code
}
- YARN grunt build - YARN grunt build: CSS - Use of the grunt plug-in -module.exports = grunt ⥤ {grunt. InitConfig ({exports = grunt.clean: {
temp: 'temp/*.js'.temp1: 'temp/**',
}
})
grunt.loadNpmTasks('grunt-contrib-clean')}Copy the code
- yarn grunt clean - yarn add grunt-contrib-clean - Implement common build tasks - yarn add grunt-sass sass -- dev-const sass = require('sass')Copy the code
const loadGruntTask = require('load-grunt-tasks')
module.exports = grunt ⥤ {grunt. InitConfig ({exports = grunt.sass: {
options: {
sourceMap: true.implementation: sass
},
main: {
files: {
'dist/css/main.css': 'src/scss/main.scss'}}},babel: {
options: {
sourceMap: true.presets: ['@babel/preset-env']},main: {
files: {
'dist/js/app.js': 'src/js/app.js'}}},watch: {
js: {
files: [' 'src/is/*.js], tasks: ['babel'] }, { css: { files: [''src/scss/*.scss], tasks: ['sass']}}}) // Grunt. LoadNpmTasks ('grunt-sass') loadgruntttasks (grunt -sass grunt.registerTask('default', ['sass', 'babel', 'watch']) }Copy the code
- yarn grunt sass - yarn grunt babel - yarn grunt watch - yarn grunt - yarn add grunt-babel @babel/core @babel/preset-env -- dev-yarn add load-grunt-tasks -- dev-yarn add grunt-contrib-watch --dev - has mostly receded from the historical stageCopy the code
Gulp
- Introduction - Recommended - A good solution to the problem of Grunt's slow build - everything is done in memory. - Multiple tasks can be executed at the same time by default. - The usage is more intuitive than Grunt. - The plugin ecosystem is also very well developed. - The most popular front-end construction system on the market at present - basic use - core features: - yarn init --yes - initialize package.json file - install Gulp module - yarn add Gulp --dev - Install Gulp module - CLI module - Create gulpfile.js file - code Gulpfile.js - gulp entry file - defines tasks by exporting member functions - has removed the synchronous code mode in the latest gulp, specifying that each task must be asynchronous. On the code -Copy the code
- gulpfile.js
- exports.foo = done ⥤ {
console.log('sjz')
done() // Indicate that the task is complete
}
Copy the code
- yarn gulp foo - exports.default = done ⥤ {console.log('default SJZ ') done() // Indicates that the task is completeCopy the code
}
-yarn gulp -gulp4.0 -const gulp = require('gulp') -gulp.task ('bar', done ⥤{Copy the code
console.log('bar')
done()
})
Copy the code
-yarn gulp bar -const {series, parallel} = require ('gulp')Copy the code
exports.task1 = done ⥤ {
setTimeout(() ⥤ {console.log('sjz1')
done() // Indicate that the task is complete
}, 1000)
exports.task2 = done ⥤ {
setTimeout(() ⥤ {console.log('sjz2')
done() // Indicate that the task is complete
}, 1000)
exports.task3 = done ⥤ {
setTimeout(() ⥤ {console.log('sjz3')
done() // Indicate that the task is complete
}, 1000)}exports.foo = series(task1, task2, task3)
exports.bar = parallel(task1, task2, task3)
Copy the code
- yarn gulp foo - yarn gulp bar - three methods of gulp asynchronous task -exme. callback = done ⥤ {console.log(' SJZ callback') done() // Mark task completionCopy the code
}
exports.callback_error = done ⥤ {
console.log('sjz callback_error')
done(new Error('task failed')) // Indicate that the task is complete
}
Copy the code
- yarn gulp callback - yarn gulp callback_error-exports. promise = done ⥤ {console.log(' SJZ promise') return Promise.resolve()Copy the code
}
exports.promise_error = done ⥤ {
console.log('sjz Promise error')
return Promise.reject(new Error('task failed'))}Copy the code
- yarn gulp promise
- yarn gulp promise_error
- constTimeout = time ⥤ {return new Promise(resolve ⥤ {
setTimeout(resolve, time)
})
}
exports.async = async () ⥤ {
console.log('async task')
await timeout(1000)}Copy the code
- yarn gulp async
- const fs = require('fs')
Copy the code
exports.stream = () ⥤ {
console.log('sjz stream')
const readStream = fs.createReadStream('package.json')
const writeStream = fs.createReadStream('package.json')
return
}
exports.stream1 = done ⥤ {
console.log('sjz stream1')
const readStream = fs.createReadStream('package.json')
const writeStream = fs.createWriteStream('temp.txt')
readStream.pipe(writeStream)
readStream.on('end', () ⥤ {done()})}Copy the code
-yarn gulp stream -gulp build process -const fs = require('fs')Copy the code
const {} = require('stream')
exports.default = () ⥤ {
// File read stream
const read = fs.createReadStream('normalize.css')
// Write the file to the stream
const write = fs.createWriteStream('normalize.min.css')
/ / transition flow
const transform = new Transform({
transform: (chunk, encoding, callback) ⥤ {
// The core conversion process is implemented
// chunk ⥤ What is read in the read stream (Buffer)
const input = chunk.toString()
input.replace(/\s+/g.' ').replace(/ / \ \ *. +? \*\//g.' ')
callback(null, input)
}
})
// Import the read file into the write file stream
read
.pipe(transform) / / conversion
.pipe(write) / / write
return read
}
Copy the code
-const {SRC, dest} = require('gulp') -yarn gulp - the streaming build system - const {SRC, dest} = require('gulp')Copy the code
const cleanCss = require('gulp-clean-css')
const rename = require('gulp-rename')
exports⥤. Default = () {return src('src/*.css')
.pipe(cleanCss())
.pipe(rename({ extname: '.min.css' }))
.pipe(dest('dist'))}Copy the code
- yarn gulp -yarn add gulp-clean-css -- dev-yarn add gulp-rename -- dev-gulp Automatic build cases - Prepare web application cases to be built. - git clone https://github.com/zce/zce-gulp-demo - open directory - code with vscode zce - gulp - demo/web application case analysis - public directory - Files that do not need to be processed and will be copied directly to the build folder - SRC directory - where code is written during development - all files in this folder will be built. -yarn add gulp --dev - create gulpfile.js file as an entry file - style compile task - const {SRC, dest} = require('gulp')Copy the code
const sass = require('gulp-sass')
exportsStyle = () ⥤ {return src('src/assets/styles/*.scss', { base: 'src' } )
.pipe(sass({ outputStyle: 'expanded' }))
.pipe(dest('dist'))}module.exports = {
style
}
Copy the code
-yarn gulp style -yarn add gulp-sass --dev - script file compilation -const {SRC, dest} = require('gulp')Copy the code
const babel = require('gulp-babel')
exports.script = () ⥤ {
return src('src/assets/scripts/*.js', { base: 'src' } )
.pipe(babel({ presets: ['@babel/preset-env'] }))
.pipe(dest('dist'))}module.exports = {
script
}
Copy the code
-yarn gulp script -yarn add gulp-babel -- dev-yarn add @babel/ core@babel /preset-env --dev - page file compilation task -const {SRC, preset) dest } = require('gulp')Copy the code
const swig = require('gulp-swig')
const data = {
menus: [].pkg: require('package.json'),
date: new Date()}exports.page = () ⥤ {
return src('src/*.html', { base: 'src' } )
.pipe(swig({ data }))
.pipe(dest('dist'))}module.exports = {
page
}
Copy the code
-yarn add gulp-swig --dev - gulp- const {SRC, dest} = require('gulp') -yarn add gulp-swig --dev - gulp- const {SRC, dest} = require('gulp')Copy the code
const imagemin = require('gulp-imagemin')
exports.image = () ⥤ {
return src('src/assets/images/**', { base: 'src' } )
.pipe(imagemin())
.pipe(dest('dist'))}exports.font = () ⥤ {
return src('src/assets/fonts/**', { base: 'src' } )
.pipe(imagemin())
.pipe(dest('dist'))}module.exports = {
image,
font
}
Copy the code
-yarn gulp image -yarn gulp gulp font -yarn add gulp-imagemin --dev - gulp-imagemin -- const {SRC, dest} = require('gulp')Copy the code
exports.extra = () ⥤ {
return src('public/**', { base: 'public' } )
.pipe(dest('dist'))}module.exports = {
extra
}
Copy the code
-- dev-const loadPlugins = require('gulp-load-plugins')Copy the code
constPlugins = loadPlugins() - replaceCopy the code
- const {SRC, dest} = require('gulp')Copy the code
exportsStyle = () ⥤ {return src('src/assets/styles/*.scss', { base: 'src' } )
.pipe(plugins.sass({ outputStyle: 'expanded' }))
.pipe(dest('dist'))}module.exports = {
style
}
Copy the code
-yarn gulp style -yarn add gulp-sass --dev - script file compilation -const {SRC, dest} = require('gulp')Copy the code
exports.script = () ⥤ {
return src('src/assets/scripts/*.js', { base: 'src' } )
.pipe(plugins.babel({ presets: ['@babel/preset-env'] }))
.pipe(dest('dist'))}module.exports = {
script
}
Copy the code
-yarn gulp script -yarn add gulp-babel -- dev-yarn add @babel/ core@babel /preset-env --dev - page file compilation task -const {SRC, preset) dest } = require('gulp')Copy the code
const data = {
menus: [].pkg: require('package.json'),
date: new Date()}exports.page = () ⥤ {
return src('src/*.html', { base: 'src' } )
.pipe(plugins.swig({ data }))
.pipe(dest('dist'))}module.exports = {
page
}
Copy the code
-yarn add gulp-swig --dev - gulp- const {SRC, dest} = require('gulp') -yarn add gulp-swig --dev - gulp- const {SRC, dest} = require('gulp')Copy the code
exports.image = () ⥤ {
return src('src/assets/images/**', { base: 'src' } )
.pipe(plugins.imagemin())
.pipe(dest('dist'))}exports.font = () ⥤ {
return src('src/assets/fonts/**', { base: 'src' } )
.pipe(plugins.imagemin())
.pipe(dest('dist'))}module.exports = {
image,
font
}
Copy the code
- yarn gulp image-yarn gulp font -yarn add gulp-imagemin --dev - hot update development server -yarn add browser-sync -- dev-const browserSync = require('browser-sync')Copy the code
const bs = browserSync.create()
exports.serve = () ⥤ {bs.init({notify: false.port: 2080.files: 'dist/**'.open: true.server: {
baseDir: 'dist'.routes: {
'/node_modules': 'node_modules'}}})}module.exports = {
serve
}
Copy the code
- const {SRC, dest, parallel, series, watch} = require('gulp') -yarn gulp serve - const {SRC, dest, parallel, series, watch} = require('gulp')Copy the code
const browserSync = require('browser-sync')
const bs = browserSync.create()
exports.serve = () ⥤ {watch('src/assets/styles/*.scss', style)
watch('src/assets/scripts/*.js', script)
watch('src/*.html', page)
Copy the code
// The following listener has no meaning when developing, Need to comment out / / watch (' SRC/assets/images / * *, image) / / watch (' SRC/assets/fonts / * *, the font) / / watch (' public / * *, extra) watch([ 'src/assets/images/**', 'src/assets/fonts/**', 'public/**' ], bs.reload) bs.init({ notify: false, port: 2080, files: 'dist/**', open: true, server: { baseDir: ['dist', 'src', 'public'], routes: { '/node_modules': 'node_modules' } } })Copy the code
}
module.exports = {
clean,
serve
}
Copy the code
- yarn gulp clean - yarn gulp serve - Problem - Swig template engine cache mechanism may cause the page will not change. Const {SRC, dest, parallel} = require('gulp')Copy the code
const compile = parallel(style, script, page, image, font)
module.exports = {
compile
}
Copy the code
- yarn gulp compile - Build task -Copy the code
const { src, dest, parallel, series } = require('gulp')
const del = require('del')
constClean = () ⥤ {return del(['dist'])}const compile = parallel(style, script, page)
// Tasks performed before going online
const build = series(clean, parallel(compile, image, font, extra))
module.exports = {
build,
clean,
develop
}
Copy the code
- yarn gulp build - yarn gulp clean - yarn add del - dev - development tasks - const develop = series (the compile, Reload - const {SRC, dest} = require('gulp')Copy the code
exportsStyle = () ⥤ {return src('src/assets/styles/*.scss', { base: 'src' } )
.pipe(plugins.sass({ outputStyle: 'expanded' }))
.pipe(dest('dist'))
.pipe(bs.reload({ stream: true}}))module.exports = {
style
}
Copy the code
-yarn gulp style -yarn add gulp-sass --dev - script file compilation -const {SRC, dest} = require('gulp')Copy the code
exports.script = () ⥤ {
return src('src/assets/scripts/*.js', { base: 'src' } )
.pipe(plugins.babel({ presets: ['@babel/preset-env'] }))
.pipe(dest('dist'))
.pipe(bs.reload({ stream: true}}))module.exports = {
script
}
Copy the code
-yarn gulp script -yarn add gulp-babel -- dev-yarn add @babel/ core@babel /preset-env --dev - page file compilation task -const {SRC, preset) dest } = require('gulp')Copy the code
const data = {
menus: [].pkg: require('package.json'),
date: new Date()}exports.page = () ⥤ {
return src('src/*.html', { base: 'src' } )
.pipe(plugins.swig({ data }))
.pipe(dest('dist'))
.pipe(bs.reload({ stream: true}}))module.exports = {
page
}
Copy the code
-yarn add gulp-swig --dev - const {SRC, dest, parallel, series, watch} = require('gulp') -yarn add gulp-swig --dev - const {SRC, dest, parallel, series, watch} = require('gulp')Copy the code
const browserSync = require('browser-sync')
const bs = browserSync.create()
exports.serve = () ⥤ {watch('src/assets/styles/*.scss', style)
watch('src/assets/scripts/*.js', script)
watch('src/*.html', page)
Copy the code
// The following listener has no meaning when developing, Need to comment out / / watch (' SRC/assets/images / * *, image) / / watch (' SRC/assets/fonts / * *, the font) / / watch (' public / * *, extra) watch([ 'src/assets/images/**', 'src/assets/fonts/**', 'public/**' ], bs.reload) bs.init({ notify: false, port: 2080, // files: 'dist/**', open: true, server: { baseDir: ['dist', 'src', 'public'], routes: { '/node_modules': 'node_modules' } } })Copy the code
}
const develop = series(compile, serve)
module.exports = {
clean,
serve,
develop
}
Copy the code
-yarn gulp build-yarn add gulp-useref -- dev-const {SRC, dest } = require('gulp')Copy the code
exports.useref = () ⥤ {
return src('dist/*.html', { base: 'dist' } )
.pipe(plugins.useref({ searchPath: ['dist'.'. '] }))
.pipe(dest('dist'))}module.exports = {
useref
}
Copy the code
-yarn gulp useref - compression HTML, CSS, JS - const {SRC, dest} = require('gulp')Copy the code
exports.useref = () ⥤ {
return src('dist/*.html', { base: 'dist' } )
.pipe(plugins.useref({ searchPath: ['dist'.'. ']}))// html,js,css
.pipe(plugins.if(/\.js$/, plugins.uglify()))
.pipe(plugins.if(/\.css$/, plugins.cleanCss()))
.pipe(plugins.if(/\.html$/, plugins.htmlmin({
collapseWhitespace: true.minifyCSS: true.minifyJS: true,
})))
.pipe(dest('release'))}module.exports = {
useref
}
Copy the code
- yarn gulp compile - yarn gulp useref - yarn add gulp-htmlmin gulp-uglify gulp-clean-css --dev - yarn add gulp-if --dev - Redesign the build process - clean -Copy the code
const { src, dest, parallel, series } = require('gulp')
const del = require('del')
constClean = () ⥤ {return del(['dist'.'temp'])}const compile = parallel(style, script, page)
// Tasks performed before going online
const build = series(clean, parallel(compile, image, font, extra))
module.exports = {
build,
clean,
develop
}
Copy the code
- const {SRC, dest} = require('gulp')Copy the code
exportsStyle = () ⥤ {return src('src/assets/styles/*.scss', { base: 'src' } )
.pipe(plugins.sass({ outputStyle: 'expanded' }))
.pipe(dest('temp'))
.pipe(bs.reload({ stream: true}}))module.exports = {
style
}
Copy the code
-yarn gulp style -yarn add gulp-sass --dev - script file compilation -const {SRC, dest} = require('gulp')Copy the code
exports.script = () ⥤ {
return src('src/assets/scripts/*.js', { base: 'src' } )
.pipe(plugins.babel({ presets: ['@babel/preset-env'] }))
.pipe(dest('temp'))
.pipe(bs.reload({ stream: true}}))module.exports = {
script
}
Copy the code
-yarn gulp script -yarn add gulp-babel -- dev-yarn add @babel/ core@babel /preset-env --dev - page file compilation task -const {SRC, preset) dest } = require('gulp')Copy the code
const data = {
menus: [].pkg: require('package.json'),
date: new Date()}exports.page = () ⥤ {
return src('src/*.html', { base: 'src' } )
.pipe(plugins.swig({ data }))
.pipe(dest('temp'))
.pipe(bs.reload({ stream: true}}))module.exports = {
page
}
Copy the code
-yarn add gulp-swig -- dev-serve-const {SRC, dest, parallel, series, watch } = require('gulp')Copy the code
const browserSync = require('browser-sync')
const bs = browserSync.create()
exports.serve = () ⥤ {watch('src/assets/styles/*.scss', style)
watch('src/assets/scripts/*.js', script)
watch('src/*.html', page)
Copy the code
// The following listener has no meaning when developing, Need to comment out / / watch (' SRC/assets/images / * *, image) / / watch (' SRC/assets/fonts / * *, the font) / / watch (' public / * *, extra) watch([ 'src/assets/images/**', 'src/assets/fonts/**', 'public/**' ], bs.reload) bs.init({ notify: false, port: 2080, // files: 'dist/**', open: true, server: { baseDir: ['temp', 'src', 'public'], routes: { '/node_modules': 'node_modules' } } })Copy the code
}
const develop = series(compile, serve)
module.exports = {
clean,
serve,
develop
}
Copy the code
- useref
- const { src, dest } = require('gulp')
Copy the code
exports.useref = () ⥤ {
return src('temp/*.html', { base: 'temp' } )
.pipe(plugins.useref({ searchPath: ['temp'.'. ']}))// html,js,css
.pipe(plugins.if(/\.js$/, plugins.uglify()))
.pipe(plugins.if(/\.css$/, plugins.cleanCss()))
.pipe(plugins.if(/\.html$/, plugins.htmlmin({
collapseWhitespace: true.minifyCSS: true.minifyJS: true,
})))
.pipe(dest('dist'))}module.exports = {
useref
}
Copy the code
- const build = series(clean, parallel(compile, useref), image, font, Extra) - YARN gulp build - yarn gulp develop - SupplementCopy the code
-
module.exports = {
clean,
build,
develop
}
Copy the code
- "scripts": {"clean": "gulp clean", "build": "gulp build", "develop": "Gulp develop",} -yarn clean-yarn build-yarn develop -. Gitignore ignore file -dist - temp - How to extract the common automated build process in multiple projects? Gulpfile + Gulp = Gulpfile + Gulp CLI ⥤ zce-pages - create a repository zce-pages -cd.. - Yarn Global add zce-cli - Run the -zce init nm zce-pages -cd zce-pages -git init -git remote add Origin command -git status -git add. -git commit -m "feat: Initial commit" -git push -u origin master - Extract Gulpfile to module -code. -a - Copy the contents of gulpfile.js in zce-gulp-demo to lib/index.js in zce-pages. - Copy all development dependencies in package.json under zce-gulp-demo to package.json under zCE-pages as project dependencies. - Install dependencies in zce-pages. - yarn - Delete the contents of gulpfile.js in zce-gulp-demo. - Delete the development dependencies in package.json in zce-gulp-demo Delete the node_modules folder under zCE-gulp-demo. - Use zCE-pages in zCE-gulp-demo. - Use yarn link - yarn link "zCE-pages" in zCE-pages Module. exports = require ('zce-pages') -yarn - yarn build - Gulp is not an internal command -yarn add gulp-cli -- dev-yarn build - Error: Local gulp not found -yarn add gulp -- dev-yarn build - Error: } Cannot find module './package.json' -do a new file called pages. Config. js in zce-gulp-demo. [], pkg: require('package.json'), date: Const {SRC, dest} = require('gulp') new Date()}} - update lib/index.js - const {SRC, dest} = require('gulp')Copy the code
const cwd = process.cwd()
let config = {
// default config
}
try {
const loadConfg = require(`${cwd}/pages.config.js`)
config = Object.assign({}, config, loadConfig)
} catch(e) {}
exports.page = () ⥤ {
return src('src/*.html', { base: 'src' } )
.pipe(plugins.swig({ data: config.data }))
.pipe(dest('temp'))
.pipe(bs.reload({ stream: true}}))module.exports = {
page
}
Copy the code
- yarn gulp page
- yarn build
- Cannot find module '@babel/preset-env'
- const { src, dest } = require('gulp')
Copy the code
exports.script = () ⥤ {
return src('src/assets/scripts/*.js', { base: 'src' } )
.pipe(plugins.babel({ presets: [require('@babel/preset-env')] }))
.pipe(dest('temp'))
.pipe(bs.reload({ stream: true}}))module.exports = {
script
}
Copy the code
Lib /index.js - const {SRC, dest} = require('gulp')Copy the code
const cwd = process.cwd()
let config = {
// default config
build: {
src: 'src'.dist: 'dist'.temp: 'temp'.public: 'public'.paths: {
styles: 'assets/styles/*.scss'.scripts: 'assets/scripts/*.js'.pages: '*.html'.images: 'assets/images/**'.fonts: 'assets/fonts/**'.styles: 'assets/styles/*.scss',}}}try {
const loadConfg = require(`${cwd}/pages.config.js`)
config = Object.assign({}, config, loadConfig)
} catch(e) {}
exports.page = () ⥤ {
return src('src/*.html', { base: 'src' } )
.pipe(plugins.swig({ data: config.data }))
.pipe(dest('temp'))
.pipe(bs.reload({ stream: true}}))module.exports = {page} - Replaces dead constants. Exports = {page} - Replaces dead constantsCopy the code
- clean
Copy the code
-
const { src, dest, parallel, series } = require('gulp')
const del = require('del')
constClean = () ⥤ {return del(config.build.dist, config.build.temp])
}
const compile = parallel(style, script, page)
// Tasks performed before going online
const build = series(clean, parallel(compile, image, font, extra))
module.exports = {
build,
clean,
develop
}
Copy the code
- style
- const { src, dest } = require('gulp')
Copy the code
exportsStyle = () ⥤ {return src(config.build.paths.styles, { base: config.build.src, cwd: config.build.src } )
.pipe(plugins.sass({ outputStyle: 'expanded' }))
.pipe(dest(config.build.temp))
.pipe(bs.reload({ stream: true}}))module.exports = {
style
}
Copy the code
- script
- const { src, dest } = require('gulp')
Copy the code
exports.script = () ⥤ {
return src(config.build.paths.scripts, { base: config.build.src, cwd: config.build.src })
.pipe(plugins.babel({ presets: [require('@babel/preset-env')] }))
.pipe(dest(config.build.temp))
.pipe(bs.reload({ stream: true}}))module.exports = {
script
}
Copy the code
- page
- const { src, dest } = require('gulp')
Copy the code
const cwd = process.cwd()
let config = {
// default config
}
try {
const loadConfg = require(`${cwd}/pages.config.js`)
config = Object.assign({}, config, loadConfig)
} catch(e) {}
exports.page = () ⥤ {
return src(config.build.paths.pages, { base: config.build.src, cwd: config.build.src } )
.pipe(plugins.swig({ data: config.data }))
.pipe(dest(config.build.temp))
.pipe(bs.reload({ stream: true}}))module.exports = {
page
}
Copy the code
- image/font
- const { src, dest } = require('gulp')
Copy the code
const imagemin = require('gulp-imagemin')
exports.image = () ⥤ {
return src(config.build.paths.images, { base: config.build.src, cwd: config.build.src } )
.pipe(imagemin())
.pipe(dest(config.build.dist))
}
exports.font = () ⥤ {
return src(config.build.paths.fonts, { base: config.build.src, cwd: config.build.src } )
.pipe(imagemin())
.pipe(dest(config.build.dist))
}
module.exports = {
image,
font
}
Copy the code
- extra
- const { src, dest } = require('gulp')
Copy the code
exports.extra = () ⥤ {
return src('* *', { base: config.build.public } )
.pipe(dest(config.build.dist))
}
module.exports = {
extra
}
Copy the code
- serve
- const { src, dest, parallel, series, watch } = require('gulp')
Copy the code
const browserSync = require('browser-sync')
const bs = browserSync.create()
exportsServe = () ⥤ {watch (config. Build. Paths. Styles, {cwd: config.build.src }, style)
watch(config.build.paths.scripts, { cwd: config.build.src }, script)
watch(config.build.paths.pages, { cwd: config.build.src }, page)
Copy the code
// The following listener has no meaning when developing, Need to comment out / / watch (' SRC/assets/images / * *, image) / / watch (' SRC/assets/fonts / * *, the font) / / watch (' public / * *, extra) watch([ config.build.paths.images, config.build.paths.fonts, // 'public/**' ], { cwd: config.build.src }, bs.reload) watch([ '**' ], { cwd: config.build.public }, bs.reload) bs.init({ notify: false, port: 2080, // files: 'dist/**', open: true, server: { baseDir: [config.build.temp, config.build.src, config.build.public], routes: { '/node_modules': 'node_modules' } } }) }Copy the code
const develop = series(compile, serve)
module.exports = {
clean,
serve,
develop
}
Copy the code
- useref
- const { src, dest } = require('gulp')
Copy the code
exports.useref = () ⥤ {
return src(config.build.paths.pages, { base: config.build.temp, cwd: config.build.temp } )
.pipe(plugins.useref({ searchPath: [config.build.temp, '. ']}))// html,js,css
.pipe(plugins.if(/\.js$/, plugins.uglify()))
.pipe(plugins.if(/\.css$/, plugins.cleanCss()))
.pipe(plugins.if(/\.html$/, plugins.htmlmin({
collapseWhitespace: true.minifyCSS: true.minifyJS: true,
})))
.pipe(dest(config.build.dist))
}
module.exports = {
useref
}
Copy the code
- yarn build-zce-gulp - addpages. Config. js = {Copy the code
build: {
src: 'src'.dist: 'release'.temp: '.tmp'.public: 'public'.paths: {
styles: 'assets/styles/*.scss'.scripts: 'assets/scripts/*.js'.pages: '*.html'.images: 'assets/images/**'.fonts: 'assets/fonts/**'.styles: 'assets/styles/*.scss',}}data: {
menus: [].pkg: require('package.json'),
date: new Date()}}Copy the code
- Package Gulp CLI - Delete the gulpfile.js file in zce-gulp-demo. - yarn Gulp - No gulpfile found - yarn Gulp --gulpfile /node_modules/zce-pages/lib/index.js - Task never defined: Default-yarn gulp build --gulpfile./node_modules/zce-pages/lib/index.js - Working directory change to D:\zce\Desktop\zce-gulp-demo\node_modules\zce-pages\lib - yarn gulp build --gulpfile /node_modules/zce-pages/lib/index.js -- cwd. - This file runs normally, but parameter transmission is complicated. - Create the bin/zce-pages file in the zce-pages directory as the CLI entry file. - "bin": "bin/zce-pages. Js "- "bin": {Copy the code
zp: "zce-pages"
}
Copy the code
- Prone to conflict - content - #! /usr/bin/env nodeCopy the code
console.log("zce/pages") -Copy the code
- 1, yarn unlink - 2, yarn link - You can directly run the command line file bin/zce-pages. Zce /pages - Contents - #! /usr/bin/env nodeCopy the code
require('gulp/bin/gulp') -Copy the code
- Zce-pages - Problem: No gulpfile found - ContentsCopy the code
#! /usr/bin/env node
console.log(process.agv)
require('gulp/bin/gulp')
Copy the code
- Run zce-pages -- SDFS SDFS - Result:Copy the code
[
'C:\\Develop\\node\\node'.'C:\\Users\\zce\\AppData\\Local\\Yarn\\Data\\link\\zce-pages\\bin\\zce-pages.js'.'--sdfs'.'sdfs'
]
Copy the code
- No gulpfile found - ContentsCopy the code
#! /usr/bin/env node
process.agv.push('--cwd')
process.agv.push(process.cwd())
process.agv.push('--gulpfile')
process.agv.push(require.resolve('.. '))
require('gulp/bin/gulp')
Copy the code
-use -cd.. -cd zce-gulp-demo-zce-pages build-ok ~ -publish and use the module - modify the files properties in package.json in the zce-pages directoryCopy the code
"files": [
"bin"."lib"
]
Copy the code
- cd .. -cd zce-pages -git add. -git commit -m "feat: update package" -git push-yarn publish - - yarn publish - registry https://registry.yranpkg.com - use - CD.. - mkdir zce-pages-demo - CD zce-pages-demo - Vscode open - code. - Copy of zce - gulp - public/SRC/directory of the demo pages. Config. Js to zce - demo directory - initialization package. Json - yarn init - yes - yarn add zce - pages - the dev - yarn zce-pages build - add scripts to package.json - "scripts": {"clean": "zce-pages clean", "build": "zce-pages build", "develop": "zce-pages develop", }Copy the code
FIS
- Introduction - A build system launched by the front end team. - Initially only for their internal projects. - After open source, it became popular in China. - FIS is more of a bundle than a microkernel-specific build system such as Grunt/Gulp, which integrates as many of the typical requirements in our system as possible internally. - For example, we can easily handle things like resource loading, modular development, code deployment, and even performance optimization in FIS - because it is large and comprehensive, it is popular in many domestic projects. - Basic use of FIS - The core feature of FIS is a high degree of integration. It integrates the common build tasks and debugging tasks in the front-end daily development process internally. - Developers can configure the work we need to do in the build process with a simple configuration file - there are many built-in tasks - built-in Web Server for debugging, - YARN Global add FIS3 - Use Vscode to open the web application prepared in advance - code fis-sample-r-FIS3 release - Automatically build project to temporary directory under current logged-in user of OS :.fis3-temp - Put build result in current directory - fis3 release -d Output - only resource location done - no code conversion done - add fIS-conf.js file - content - fis.match('*.{js, scss, png}', {Copy the code
release: ‘/assets/$0’ })
- fis - special global object - $0 - represents the original directory structure of the current file - compile and compressCopy the code
Copy the code
-
summary
-
If you are a beginner, FIS is more suitable
- But if your requirements are flexible, Gulp/Grunt is a better choice.
-
Novices need rules, and veterans generally crave freedom.
- It is for this reason that small but beautiful tools like Grunt/Gulp are popular.
-