自动化构建
源代码 -> 生成代码
输入 scss scss/main.scss css/style.css
即可构建出 css
缺点:每次都需要重复输入这个复杂的命令
npm script 就是用来解决这个问题
1 2 3 4 5
| { "scripts": { "build": "sass scss/main.scss css/style.css --watch", }, }
|
接下来安装 browser-sync
用于启动测试服务器
1
| yarn add browser-sync --dev
|
运行测试服务器 npm run serve
1 2 3 4 5
| { "scripts": { "serve": "browser-sync . --files \"css/*.css\" }, }
|
不过这里可能有个问题,如果在运行测试服务器之前,没有生成 css,浏览器就没办法展示样式
- 这里就可以用到 npm script 的钩子机制
preserve
在启动任务之前,让 build 先去工作
1 2 3 4 5
| { "scripts": { "preserve": "yarn build" }, }
|
如果给 build 增加 --watch
参数,scss 会阻塞命令行等待文件变化,就会导致 browser-sync
没办法直接去工作
1 2 3 4 5
| { "scripts": { "start": "run-p build serve" }, }
|
常用工具
- 严格来说 Webpack 是模块打包工具
- Grunt、Gulp、FIS 是自动化构建工具
- Grunt 老牌构建工具,插件生态完善,但是它的工作过程是基于临时文件实现的,所以构建速度较慢(Scss 编译后就会将结果写入到临时文件,下一个插件读取这个临时文件进行操作,环节越多读取文件次数越多)
- Gulp 基于内存实现的,对文件的处理都是在内存中实现,速度快一些,默认同时支持多个任务,目前比较流行
- FIS 百度团队研发,把项目中最典型需求都集成到内部,大而全
Grunt
基本使用
1 2
| yarn init –yes yarn add grunt
|
新建 gruntfile.js
- Grunt 的入口文件,用于定义一些需要 Grunt 自动执行的任务
- 需要导出一个函数,该函数接收一个 grunt 对象,内部提供一些创建任务可以用到的 API
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| module.exports = grunt => { grunt.registerTask('foo', '任务描述', () => { console.log('foo') }) grunt.registerTask('bar', () => { console.log('bar') }) grunt.registerTask('default', ['foo', 'bar']) grunt.registerTask('async-task', function () { const done = this.async() setTimeout(() => { console.log('async task working~') done() }, 1000) }) }
|
标记任务失败
任务函数执行过程中如果返回 false,则意味着此任务执行失败
如果一个任务列表中的某个任务执行失败,则后续任务默认不会运行
除非 grunt 运行时指定 --force
参数强制执行
异步函数中标记当前任务执行失败的方式是为回调函数指定一个 false 的实参
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| module.exports = grunt => { grunt.registerTask('bad', () => { console.log('bad working~') return false }) grunt.registerTask('foo', () => { console.log('foo working~') }) grunt.registerTask('bar', () => { console.log('bar working~') }) grunt.registerTask('default', ['foo', 'bad', 'bar']) grunt.registerTask('bad-async', function () { const done = this.async() setTimeout(() => { console.log('async task working~') done(false) }, 1000) }) }
|
配置选项方法
用 init
配置,用 grunt.config
获取属性值
1 2 3 4 5 6 7 8 9 10
| module.exports = grunt => { grunt.initConfig({ foo: { bar: 123, }, }) grunt.registerTask('foo', () => { console.log(grunt.config('foo.bar')) }) }
|
多目标任务
用 init
配置,通过 this
拿到执行的名称和数据
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| module.exports = grunt => { grunt.initConfig({ build: { options: { msg: 'task options', }, foo: { options: { msg: 'foo target options', }, }, bar: '456', }, }) grunt.registerMultiTask('build', function () { console.log(this.options()) console.log(`target:${this.target},data:${this.data}`) }) }
|
Grunt 插件
安装 grunt-contrib-clean
1
| yarn add grunt-contrib-clean --dev
|
将 temp 目录下所有文件都清除
1 2 3 4 5 6 7 8 9
| module.exports = grunt => { grunt.initConfig({ clean: { temp: 'temp/**', }, })
grunt.loadNpmTasks('grunt-contrib-clean') }
|
安装 grunt-sass
、sass
1
| yarn add grunt-sass sass --dev
|
安装 grunt-babal
、babel
1
| yarn add grunt-babel @babel/core @babel/preset-env --dev
|
随着 gruntfile.js
越来越复杂,loadNpmTasks
操作也会越来越多,可以使用 load-grunt-tasks
1
| yarn add load-grunt-tasks --dev
|
当文件修改完,需要自动去编译,这时需要另外一个插件 grunt-contrib-watch
1
| yarn add grunt-contrib-watch --dev
|
Grunt 使用插件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
| const sass = require('sass') const loadGruntTasks = require('load-grunt-tasks')
module.exports = grunt => { grunt.initConfig({ 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/js/*.js'], tasks: ['babel'], }, css: { files: ['src/scss/*.scss'], tasks: ['sass'], }, }, })
loadGruntTasks(grunt) grunt.registerTask('default', ['sass', 'babel', 'watch']) }
|
Gulp
基本使用
Gulp 核心特点:高效易用
- 安装 Gulp 同时会自动安装一个叫 gulpcli 模块
1 2
| yarn init --yes yarn add gulp --dev
|
创建 gulpfile.js
入口,导出一个 foo 函数
1 2 3
| exports.foo = () => { console.log('foo task working~') }
|
执行 yarn gulp foo
,发现有报错
- gulp 取消了同步代码模式,约定每一个任务都是异步的,当任务执行完需要通过回调函数标记任务执行完毕
1 2 3
| [11:04:54] The following tasks did not complete: foo [11:04:54] Did you forget to signal async completion? error Command failed with exit code 1.
|
gulp 4.0 以后的保留了 gulp.task
API
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| exports.foo = done => { console.log('foo task working~') done() }
exports.default = done => { console.log('default task working~') done() }
const gulp = require('gulp') gulp.task('bar', done => { console.log('bar task working~') done() })
|
组合任务
通过 series
、parallel
组合多个任务
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| const { series, parallel } = require('gulp')
const task1 = done => { setTimeout(() => { console.log('task1 working~') done() }, 1000) }
const task2 = done => { setTimeout(() => { console.log('task2 working~') done() }, 1000) }
const task3 = done => { setTimeout(() => { console.log('task3 working~') done() }, 1000) }
exports.foo = series(task1, task2, task3)
exports.bar = parallel(task1, task2, task3)
|
异步任务
- 回调函数
- Promsie、async 和 await(Node 8 以上的版本)
- Stram 方式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
| const fs = require('fs')
exports.callback = done => { console.log('callback task') done() } exports.callback_error = done => { console.log('callback task') done(new Error('task failed')) }
exports.promise = () => { console.log('promise task') return Promise.resolve() } exports.promise_error = () => { console.log('promise task') return Promise.reject(new Error('task failed')) }
const timeout = time => { return new Promise(resolve => { setTimeout(resolve, time) }) } exports.async = async () => { await timeout(1000) console.log('async task') }
exports.stream = () => { const readStream = fs.createReadStream('package.json') const writeStream = fs.createWriteStream('temp.txt') readStream.pipe(writeStream)
return readStream }
|
核心工作原理
- The streaming build system
stream 的 Transform 类型可以创建文件转换流对象,里面需要指定 transform 属性(转化流核心转换过程)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| const fs = require('fs') const { Transform } = require('stream')
exports.default = () => { const readStream = fs.createReadStream('normalize.css') const writeStream = fs.createWriteStream('normalize.min.css') const transformStream = new Transform({ transform: (chunk, encoding, callback) => { const input = chunk.toString() const output = input.replace(/\s+/g, '').replace(/\/\*.+?\*\//g, '') callback(null, output) }, })
return readStream .pipe(transformStream) .pipe(writeStream) }
|
文件操作 API
1 2
| yarn add gulp-clean-css --dev yarn add gulp-rename --dev
|
通过 src 去 pipe 到插件转换流,再去 pipe 到写入流的过程就是使用 gulp 常规过程
1 2 3 4 5 6 7 8 9 10
| const { src, dest } = require('gulp') 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')) }
|
Gulp 案例
样式编译
下载代码
1
| git clone https://github.com/zec/zec-gulp-demo.git
|
安装 gulp
、gulp-sass
- 安装
gulp-sass
会安装 node-sass(是 C++ 模块),内部会有对 C++ 程序集的依赖,二进制包需要国外站点去下载,有时会下载不下来,可以配置淘宝镜像源下载
1 2
| yarn add gulp --dev yarn add gulp-sass --dev
|
1 2 3 4 5 6 7 8 9 10 11 12
| const { src, dest } = require('gulp') const sass = require('gulp-sass')
const style = () => { return src(`src/assets/styles/*.scss`, { base: 'src' }) .pipe(sass({ outputStyle: 'expanded' })) .pipe(dest('dist')) }
module.exports = { style, }
|
脚本编译
安装 gulp-babel
、@babel/core
、@babel/preset-env
1 2
| yarn add gulp-babel --dev yarn add @babel/core @babel/preset-env --dev
|
1 2 3 4 5 6 7 8 9 10 11 12
| const { src, dest } = require('gulp') const babel = require('gulp-babel')
const script = () => { return src(`src/assets/scripts/*.js`, { base: 'src' }) .pipe(babel({ presets: ['@babel/preset-env'] })) .pipe(dest('dist')) }
module.exports = { script, }
|
页面模板编译
安装 gulp-swig
1
| yarn add gulp-swig --dev
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
| const { src, dest, parallel } = require('gulp') const swig = require('gulp-swig')
const data = { 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: '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(swig({ data })).pipe(dest('dist')) }
const compile = parallel(style, script, page)
module.exports = { compile }
|
图片和字体文件的转换
安装 gulp-imagemin
- 内部依赖的模块也是通过 C++ 模块,需要下载二进制程序集(大部分 GitHub 下载),但是这个没办法配置镜像
1
| yarn add gulp-imagemin --dev
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| const { src, dest, parallel } = require('gulp') 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')) }
const compile = parallel(style, script, page, image, font)
module.exports = { compile }
|
其它文件及文件清除
安装 del
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| const { src, dest, parallel, series } = require('gulp') const del = require('del')
const clean = () => { return del(['dist']) }
const compile = parallel(style, script, page, image, font)
const build = series(clean, parallel(compile, extra))
module.exports = { build, }
|
自动加载插件
安装 gulp-load-plugins
1
| yarn add gulp-load-plugins --dev
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
| const { src, dest, parallel, series } = require('gulp') const del = require('del') const loadPlugins = require('gulp-load-plugins') const plugins = loadPlugins()
const data = {...}
const clean = () => { return del(['dist']) }
const style = () => { return src(`src/assets/styles/*.scss`, { base: 'src' }) .pipe(plugins.sass({ outputStyle: 'expanded' })) .pipe(dest('dist')) }
const script = () => { return src(`src/assets/scripts/*.js`, { base: 'src' }) .pipe(plugins.babel({ presets: ['@babel/preset-env'] })) .pipe(dest('dist')) }
const page = () => { return src(`src/**/*.html`, { base: 'src' }).pipe(plugins.swig({ data })).pipe(dest('dist')) }
const image = () => { return src(`src/assets/images/**`, { base: 'src' }).pipe(plugins.imagemin()).pipe(dest('dist')) }
const font = () => { return src(`src/assets/fonts/**`, { base: 'src' }).pipe(plugins.imagemin()).pipe(dest('dist')) }
const extra = () => { return src(`public/**`, { base: 'public' }).pipe(dest('dist')) }
const compile = parallel(style, script, page, image, font)
const build = series(clean, parallel(compile, extra))
module.exports = { build, }
|
热更新开发服务器
安装 browser-sync
1
| yarn add browser-sync --dev
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| const browserSync = require('browser-sync')
const bs = browserSync.create()
const serve = () => { bs.init({ notify: false, port: 2080, files: 'dist/**', server: { baseDir: 'dist', routes: { '/node_modules': 'node_modules', }, }, }) }
module.exports = { serve, }
|
监听变化及构建优化
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
| const { src, dest, parallel, series, watch } = require('gulp')
const style = () => { return src(`src/assets/styles/*.scss`, { base: 'src' }) .pipe(plugins.sass({ outputStyle: 'expanded' })) .pipe(dest('dist')) .pipe(bs.reload({ stream: true })) }
const script = () => { return src(`src/assets/scripts/*.js`, { base: 'src' }) .pipe(plugins.babel({ presets: ['@babel/preset-env'] })) .pipe(dest('dist')) .pipe(bs.reload({ stream: true })) }
const page = () => { return src(`src/**/*.html`, { base: 'src' }) .pipe(plugins.swig({ data })) .pipe(dest('dist')) .pipe(bs.reload({ stream: true })) }
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', 'src', 'public'], routes: { '/node_modules': 'node_modules', }, }, }) }
const compile = parallel(style, script, page) const build = series(clean, parallel(compile, image, font, extra)) const develop = series(compile, serve)
|
useref 文件引用处理
有些文件依赖的是 node_modules
下的文件,这里并没有将其拷贝到 dist 目录,如果上线肯定找不到,本地能找到是因为做了路由映射
1
| yarn add gulp-useref --dev
|
构建注释
1 2 3 4 5 6
| <link rel="stylesheet" href="/node_modules/bootstrap/dist/css/bootstrap.css">
<link rel="stylesheet" href="assets/styles/main.css">
|
1 2 3 4 5
| const useref = () => { return src('dist/*.html', { base: 'dist' }) .pipe(plugins.useref({ searchPath: ['dist', '.'] })) .pipe(dest('dist')) }
|
分别压缩 HTML、CSS、JS
- 另外还需要判断对不同文件的操作,这个时候就需要一个额外的插件去判断
1 2
| yarn add gulp-htmlmin gulp-uglify gulp-clean-css --dev yarn add gulp-if --dev
|
操作时会发现 main.css
没有内容,这时因为文件读写冲突,一边读一边写
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| const useref = () => { return src('dist/*.html', { base: 'dist' }) .pipe(plugins.useref({ searchPath: ['dist', '.'] })) .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')) }
|
重新规划构建过程
useref 打破了我们的目录结构
- 打包上线是 dist 目录,而 useref 把目录改成了 release
增加临时目录 temp
script
、style
、page
放到 temp 目录
image
、font
、extra
不需要改,这三个只需要 build 时候去做,只有被 useref 影响才需要
serve
里的 baseDir 需要改为 temp
useref
src 从 temp 里取,把结果放到 dist
目录里
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107
| const { src, dest, parallel, series, watch } = require('gulp') const del = require('del') const browserSync = require('browser-sync') const loadPlugins = require('gulp-load-plugins') const plugins = loadPlugins() const bs = browserSync.create()
const clean = () => { return del(['dist', 'temp']) }
const style = () => { return src('src/assets/styles/*.scss', { base: 'src' }) .pipe(plugins.sass({ outputStyle: 'expanded' })) .pipe(dest('temp')) .pipe(bs.reload({ stream: true })) }
const script = () => { return src('src/assets/scripts/*.js', { base: 'src' }) .pipe(plugins.babel({ presets: ['@babel/preset-env'] })) .pipe(dest('temp')) .pipe(bs.reload({ stream: true })) }
const page = () => { return src('src/*.html', { base: 'src' }) .pipe(plugins.swig({ data, defaults: { cache: false } })) .pipe(dest('temp')) .pipe(bs.reload({ stream: true })) }
const image = () => { return src('src/assets/images/**', { base: 'src' }) .pipe(plugins.imagemin()) .pipe(dest('dist')) }
const font = () => { return src('src/assets/fonts/**', { base: 'src' }) .pipe(plugins.imagemin()) .pipe(dest('dist')) }
const extra = () => { return src('public/**', { base: 'public' }) .pipe(dest('dist')) }
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: ['temp', 'src', 'public'], routes: { '/node_modules': 'node_modules' } } }) }
const useref = () => { return src('temp/*.html', { base: 'temp' }) .pipe(plugins.useref({ searchPath: ['temp', '.'] })) .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')) }
const compile = parallel(style, script, page) const build = series( clean, parallel( series(compile, useref), image, font, extra ) ) const develop = series(compile, serve)
module.exports = { clean, build, develop }
|
构建完这套系统,如果你不想写文档说明,导出几个常用即可,clean
、build
、develop
- 并在
package.json
中增加 script 命令
1 2 3 4 5
| "scripts": { "clean": "gulp clean", "build": "gulp build", "develop": "gulp develop" },
|
封装工作流
提取多个项目共同的自动化构建过程(Don’t repeat yourself)
提取 gulpfile
zce-gulp-demo
这里叫 A,zce-pages
这里叫 B
- 在命令行输入
code . -a
在同一窗口打开这个项目
把 A 项目工作流提取到 B 项目中,操作步骤如下:
- 把 A 的
gulpfile.js
内容复制到 B 的 lib/index.js
- 把 A 的
package.json
中的 devDependencies
复制到 B 中 dependencies
- 把 A 的
package.json
中的 devDependencies
全部删除,并把 node_modules
全部删除
- 把 B link 到全局,切换到 A 输入命令
yarn link zce-pages
,B 项目会通过软链接形式链过来
- 在 B 中新建
gulpfile.js
新增 module.exports = require('zce-pages')
内容
- 执行
yarn build
执行 yarn build
我这边报错了,是因为 gulp-sass
没有下载下来
1 2 3 4 5
| Error in plugin "gulp-sass" Message:
gulp-sass no longer has a default Sass compiler; please set one yourself. Both the "sass" and "node-sass" packages are permitted.
|
解决:安装 sass
修改 lib/index.js
1 2 3 4 5 6 7 8
| const sass = require('gulp-sass')(require('sass'))
const style = () => { return src('src/assets/styles/*.scss', { base: 'src' }) .pipe(sass({ outputStyle: 'expanded' })) .pipe(dest('temp')) .pipe(bs.reload({ stream: true })) }
|
抽象路径配置
对于代码里写死的路径,如 sass 的路径,这样不是很灵活,我们可以抽象一下形成配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| const cwd = process.cwd() let 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/**' } } }
try { const loadConfig = require(`${cwd}/pages.config.js`) config = Object.assign({}, config, loadConfig) } catch (e) {}
const style = () => { return src(config.build.paths.styles, { base: config.build.src, cwd: config.build.src }) .pipe(sass({ outputStyle: 'expanded' })) .pipe(dest(config.build.temp)) .pipe(bs.reload({ stream: true })) }
|
包装 Gulp Cli
gulpfile.js
里只是写了个 module.exports = require('zce-pages')
,其实有点冗余,我们希望没有 gulpfile.js
也能正常工作
1
| yarn gulp build --gulpfile ./node_modules/zce-pages/lib/index.js --cwd .
|
不过这么多参数就很复杂了,可以集成 cli
创建 bin/zce-pages.js
作为 cli 执行入口
在 package.json
中增加 bin
字段
1
| "bin": "bin/zce-pages.js",
|
修改 zce-pages.js
process.argv
是一个数组
require
是载入这个模块,require.resolve
是找到这个模块所在的路径
1 2 3 4 5 6 7 8
| #!/usr/bin/env node
process.argv.push('--cwd') process.argv.push(process.cwd()) process.argv.push('--gulpfile') process.argv.push(require.resolve('..'))
require('gulp/bin/gulp')
|
代码提交完,就可以使用 publish 提交 git
1
| yarn publish --registry https://registry.yarnpkg.com
|
同步时可能会有问题,因为你发布的是 npm 源,但是你是从淘宝源下载,可能会存在同步问题,可以进入淘宝镜像搜一下你 publish 的包,然后更新
总结
新建项目如果想要使用工作流,直接运行 package.json
中的命令即可
创建的 cli 是 node_modules/bin/zce-pages.cmd
,这个文件中是通过 node 去执行 zce-pages/bin/zce-pages.js
在 node_modules
找到 zce-pages/bin/zce-pages.js
,里面就是告诉 gulp 工作时的工作目录和 gulpfile 的工作目录
之后执行 gulp/bin/gulp
就可以执行 gulpifle 了,完成整个工作流过程
FIS
高度集成,只需要简单配置
relase 解决的资源定位
新建 fis-conf.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| fis.match('*.{js,scss,png}', { release: '/assets/$0', })
fis.match('**/*.scss', { rExt: '.css', parser: fis.plugin('node-sass'), optimizer: fis.plugin('clean-css'), })
fis.match('**/*.js', { parser: fis.plugin('babel-6.x'), optimizer: fis.plugin('uglify-js'), })
|
查看转换过程中转换的配置