工程化不等于某个工具,工具只是帮助我们落实工程化的方式或者手段。
1.脚手架工具
yeoman 工程化项目等等
Plop 小型脚手架工具,创建项目中特定的文件,一般集成到项目中。
2.自动化构建
脱离运行环境的问题
使用提高效率的语法、规范和标准
2.1 自动化构建工具
常用自动化构建工具: Grunt、Gulp、FIS
webpack只是模块打包工具
Grunt:支持所有的构建需求,但是每次编译都会产生临时文件。处理的文件越多,产生的临时文件就越多,效率会很低。
Gulp:是依赖于内存,现在比加流行的。
FIS: 大而全,百度封装了一整套,不够灵活。
2.2 gulp自动化构建流程
目录结构
└── my-awesome-pages ································· project root
├─ public ········································· static folder
│ └─ favicon.ico ································· static file (unprocessed)
├─ src ············································ source folder
│ ├─ assets ······································ assets folder
│ │ ├─ fonts ···································· fonts folder
│ │ │ └─ pages.ttf ····························· font file (imagemin)
│ │ ├─ images ··································· images folder
│ │ │ └─ logo.png ······························ image file (imagemin)
│ │ ├─ scripts ·································· scripts folder
│ │ │ └─ main.js ······························· script file (babel / uglify)
│ │ └─ styles ··································· styles folder
│ │ ├─ _variables.scss ······················· partial sass file (dont output)
│ │ └─ main.scss ····························· entry scss file (scss / postcss)
│ ├─ layouts ····································· layouts folder
│ │ └─ basic.html ······························· layout file (dont output)
│ ├─ partials ···································· partials folder
│ │ └─ header.html ······························ partial file (dont output)
│ ├─ about.html ·································· page file (use layout & partials)
│ └─ index.html ·································· page file (use layout & partials)
├─ .csscomb.json ·································· csscomb config file
├─ .editorconfig ·································· editor config file
├─ .gitignore ····································· git ignore file
├─ .travis.yml ···································· travis ci config file
├─ CHANGELOG.md ··································· repo changelog
├─ LICENSE ········································ repo license
├─ README.md ······································ repo readme
├─ gulpfile.js ···································· gulp tasks file
├─ package.json ··································· package file
└─ yarn.lock ······································ yarn lock file
1. yarn add gulp -D ,新建一个gulpfile.js 添加代码如下,运行yarn gulp test,如果生成dist目录说明成功了。
// 实现这个项目的构建任务
const { src, dest } = require('gulp')
//
const test = () => {
return src('src/**', { base: 'src'})
.pipe(dest('dist'))
}
module.exports = {
test
}
2. 实现style文件中scss的编译
-
声明style任务
-
安装gulp-sass
yarn add gulp-sass -D
-
实现:先src导入流,然后再管道流中用babel编译,最后输出到目标地址中
const sass = require('gulp-sass') const style = () => { return src('src/assets/styles/**', { base: 'src' }) .pipe(sass({ outputStyle: 'compressed' })) .pipe(dest('dist')) }
3. 实现script中js编译为es5
- 安装babel相关包
yarn add gulp-babel @babel/core @babel/preset-env -D
-
实现思路,先获取要编译的文件流,然后加上babel编译成es5到目标文件中
const babel = require('gulp-babel') const script = () => { return src('src/assets/scripts/**', { base: 'src'}) .pipe(babel({ presets: ['@babel/env'] })) .pipe(dest('dist')) }
3. 实现图片和字体打包压缩
-
安装gulp-imagemin
yarn add gulp-imagemin -D
-
实现思路就是在流中间加个图片压缩,然后到目标文件就可以了
const imagemin = require('gulp-imagemin') const image = () => { return src('src/assets/images/**', {base: 'src'}) .pipe(imagemin()) .pipe(dest('dist')) } const font = () => { return src('src/assets/fonts/**', { base: 'src'}) .pipe(imagemin()) .pipe(dest('dist'))
4. 将public目录中文件打包到dist目录
const extra = () => {
return src('public/**', { base: 'public' })
.pipe(dest('dist'))
}
5. src下面的所有html打包到dist目录
-
安装gulp-swig 和 gulp-data 依赖
yarn add gulp-swig gulp-data -D
-
实现将数据传入到swig中然后编译html
const swig = require('gulp-swig') const data = require('gulp-data') const jsondata = { menus: [ { name: 'Home', icon: 'aperture', link: 'index.html' }, { name: 'Features', link: 'features.html' }, { name: 'About', link: 'about.html' }, { name: 'Contact', link: '#', children: [ { name: 'Twitter', link: 'https://twitter.com/w_zce' }, { name: 'About', link: '[Sina Visitor System](https://weibo.com/zceme') }, { name: 'divider' }, { name: 'About', link: 'https://github.com/zce' } ] } ], pkg: require('./package.json'), date: new Date() } const page = () => { return src('src/*.html', { base: 'src'}) .pipe(data(jsondata)) .pipe(swig({ defaults: { cache: false}})) // Avoid caching when watching/compiling html templates with BrowserSync, etc. .pipe(dest('dist')) }
6. 引入gulp-load-plugins
- 安装gulp-load-plugins
yarn add gulp-load-plugins -D
-
删除gulp应用插件
const babel = require(‘gulp-babel’)
const sass = require(‘gulp-sass’)
const imagemin = require(‘gulp-imagemin’)
const swig = require(‘gulp-swig’)
const data = require('gulp-data)用以下代码代替
const gulpLoader = require(‘gulp-load-plugins’)
const plugins = gulpLoader()
这里用可以通过vscode f2键重名变量
7. 引入browser-sync监听网页变化
-
yarn add browser-sync
-
实现
const browserSync = require('browser-sync')
const compile = parallel(style, script, page)
const build = series(clean, parallel(compile, image, font, extra))
const start = series(compile, ser
const serve = () => {
bs.init({
notify: false,
port: 2080,
server: {
baseDir: ['dist'],
routes: {
'/node_modules': 'node_modules'
}
},
})
}ve)
module.exports = {
clean,
build,
start
}
-
运行yarn gulp start就可以看到网站可以正常显示了
-
serve中添加watch监听文件变化执行任务
const { src, dest, parallel, series, watch } = require('gulp')
const serve = () => {
watch('src/assets/styles/*.scss', style)
watch('src/assets/scripts/*.js', script)
watch('src/*.html', page)
watch([
'src/assets/images/**',
'src/assets/fonts/**',
'public/**'
], bs.reload)
bs.init({
notify: false,
port: 2080,
server: {
baseDir: ['dist'],
routes: {
'/node_modules': 'node_modules'
}
},
})
}
-
浏览器自动重载实现
加上pipe(bs.reload({ stream:true })),详见Browsersync + Gulp.js - Browsersync中文网
const script = () => { return src('src/assets/scripts/**', { base: 'src' }) .pipe(plugins.babel({ presets: ['@babel/env'] })) .pipe(dest('dist')) .pipe(bs.reload({ stream: true})) }
8. 用gulp-useref将html中的资源引入替换并引入到目标文件中
gulp-useref的作用: 解析HTML文件中的构建块,用useref替换对未优化脚本或样式表的引用
例子:
before
<html>
<head>
<!-- build:css css/combined.css -->
<link href="css/one.css" rel="stylesheet">
<link href="css/two.css" rel="stylesheet">
<!-- endbuild -->
</head>
<body>
<!-- build:js scripts/combined.js -->
<script type="text/javascript" src="scripts/one.js"></script>
<script type="text/javascript" src="scripts/two.js"></script>
<!-- endbuild -->
</body>
</html>
after
<html>
<head>
<link rel="stylesheet" href="css/combined.css"/>
</head>
<body>
<script src="scripts/combined.js"></script>
</body>
</html>
由于useref会先导入当前流并且输出当前流,这个时候如果在同一文件中进行则会冲突,
因此需要将html,js ,css导入temp文件夹中如下所示
const style = () => {
return src('src/assets/styles/**', { base: 'src' })
.pipe(plugins.sass({
outputStyle: 'compressed'
}))
.pipe(dest('temp'))
.pipe(bs.reload({ stream: true}))
}
const script = () => {
return src('src/assets/scripts/**', { base: 'src' })
.pipe(plugins.babel({
presets: ['@babel/env']
}))
.pipe(dest('temp'))
.pipe(bs.reload({ stream: true}))
}
const page = () => {
return src('src/*.html', { base: 'src' })
.pipe(plugins.data(jsondata))
.pipe(plugins.swig({ defaults: { cache: false } })) // Avoid caching when watching/compiling html templates with BrowserSync, etc.
.pipe(dest('temp'))
.pipe(bs.reload({ stream: true}))
}
-
yarn add gulp-useref -D
-
使用gulp-useref
const useref = ()=> {
return src('temp/**', { base: 'temp'})
.pipe(plugins.useref({
searchPath: ['temp', '.']
}))
.pipe(dest('dist'))
- build任务先执行compile,然后再执行useref
const build = series(clean, parallel(series(compile, useref), image, font, extra))
- 最后安装gulp-if 配合userref进行文件压缩
yarn add gulp-if gulp-uglify gulp-clean-css -D
const useref = ()=> {
return src('temp/**', { base: 'temp'})
.pipe(plugins.useref({
searchPath: ['temp', '.']
}))
.pipe(plugins.if(/\.js$/, plugins.uglify()))
.pipe(plugins.if(/\.js$/, plugins.cleanCss()))
.pipe(plugins.if(/\.html$/, plugins.htmlmin({
collapseWhitespace: true,
minifyCSS: true,
minifyJS: true
})))
.pipe(dest('dist'))
}
```= ()=> {
return src('temp/**', { base: 'temp'})
.pipe(plugins.useref({
searchPath: ['temp', '.']
}))
.pipe(dest('dist'))
- build任务先执行compile,然后再执行useref
const build = series(clean, parallel(series(compile, useref), image, font, extra))
- 最后安装gulp-if 配合userref进行文件压缩
yarn add gulp-if gulp-uglify gulp-clean-css -D
const useref = ()=> {
return src('temp/**', { base: 'temp'})
.pipe(plugins.useref({
searchPath: ['temp', '.']
}))
.pipe(plugins.if(/\.js$/, plugins.uglify()))
.pipe(plugins.if(/\.js$/, plugins.cleanCss()))
.pipe(plugins.if(/\.html$/, plugins.htmlmin({
collapseWhitespace: true,
minifyCSS: true,
minifyJS: true
})))
.pipe(dest('dist'))
}