流程

  1. 创建一个 node 模块,把 demo 中的 gulpfile 中的内容提取到模块的入口文件。把 demo 的开发依赖转移到模块的依赖。demo 中的 gulpfile 的内容改成:

    1. module.exports = require('chen-pages')
  2. 通过 yarn link 和 yarn link “模块名”,把模块添加到 demo 的 node_modules。

  3. 由于模块尚未发布,这时 demo 运行 gulp 命令,会找不到 gulp ,需要暂时添加 gulp-cli 和 gulp 作为开发依赖。如果模块正式发布,则无需此步骤。

  4. demo 中创建一个 pages.config.js 文件,作为约定的配置文件,把模块入口文件中的 data 项转移到里面。

image.png

  1. 在模块入口文件,原来的data项的位置,读取配置文件。原引用 data 项的地方改为 config.data。 ```javascript const cwd = process.cwd() let config = {}

try { const loadConfig = require(${cwd}/pages.config.js) config = Object.assign({}, config, loadConfig) } catch (error) { }

const page = () => { return src(‘src/*.html’, { base: ‘src’ }) .pipe(plugins.swig({ data: config.data, defaults: { cache: false } })) // 由原本的data改为data:config.data .pipe(dest(‘temp’)) .pipe(bs.reload({ stream: true })) }

  1. 6. script 任务中配置了 preset-env preset,旧的引入方式是在 demo node_modules 下找,但现在 demo 中没有安装,应该修改成 requirerequire 是在模块里面找。
  2. ```javascript
  3. const script = () => {
  4. return src('src/assets/scripts/*.js', { base: 'src' })
  5. .pipe(plugins.babel({ presets: ['@babel/preset-env'] }))
  6. .pipe(dest('temp'))
  7. .pipe(bs.reload({ stream: true }))
  8. }
  9. const script = () => {
  10. return src('src/assets/scripts/*.js', { base: 'src' })
  11. .pipe(plugins.babel({ presets: [require('@babel/preset-env')] }))
  12. .pipe(dest('temp'))
  13. .pipe(bs.reload({ stream: true }))
  14. }
  1. 至此,自动构建化工作流模块完成。

优化

抽象路径配置

把模块的入口文件中,写死的配置路径抽象到 config 对象中,这样可以实现在项目中自行修改路径。

  1. let config = {
  2. build: {
  3. src: 'src',
  4. dist: 'dist',
  5. temp: 'temp',
  6. public: 'public',
  7. paths: {
  8. styles: 'assets/styles/*.scss',
  9. scripts: 'assets/scripts/*.js',
  10. pages: '*.html',
  11. images: 'assets/images/**',
  12. fonts: 'assets/fonts/**',
  13. }
  14. }
  15. }
  16. // 原本的代码
  17. const style = () => {
  18. return src('src/assets/styles/*.scss', { base: 'src' })
  19. .pipe(plugins.sass({ outputStyle: 'expanded' }))
  20. .pipe(dest('temp'))
  21. .pipe(bs.reload({ stream: true }))
  22. }
  23. // 抽象路径后代码
  24. const style = () => {
  25. return src(config.build.paths.styles, { base: config.build.src, cwd: config.build.src }) //cwd变量可以指定相对路径,这里效果等同于 src(config.build.src + config.build.paths.styles, { base: config.build.src })
  26. .pipe(plugins.sass({ outputStyle: 'expanded' }))
  27. .pipe(dest(config.build.temp))
  28. .pipe(bs.reload({ stream: true }))
  29. }
  30. // 原本的代码
  31. const extra = () => {
  32. return src('public/**', { base: 'public' })
  33. .pipe(dest('dist'))
  34. }
  35. // 抽象路径后代码
  36. const extra = () => {
  37. return src('**', { base: config.build.public, cwd: config.build.public })
  38. .pipe(dest(config.build.dist))
  39. }
  40. // 原本的代码
  41. const serve = () => {
  42. watch('src/assets/styles/*.scss', style)
  43. watch('src/assets/scripts/*.js', script)
  44. watch('src/*.html', page)
  45. watch([
  46. 'src/assets/images/**',
  47. 'src/assets/fonts/**',
  48. 'public/**',
  49. ], bs.reload)
  50. bs.init({
  51. notify: false,
  52. // files: 'dist/**',
  53. port: 3080,
  54. // open: false,
  55. server: {
  56. baseDir: ['temp', 'src', 'public'],
  57. routes: {
  58. '/node_modules': 'node_modules'
  59. }
  60. }
  61. })
  62. }
  63. // 抽象路径后代码
  64. const serve = () => {
  65. watch(config.build.paths.styles, { cwd: config.build.src }, style)
  66. watch(config.build.paths.scripts, { cwd: config.build.src }, script)
  67. watch(config.build.paths.pages, { cwd: config.build.src }, page)
  68. watch([
  69. config.build.paths.images,
  70. config.build.paths.fonts,
  71. ], { cwd: config.build.src }, bs.reload)
  72. watch('**', { cwd: config.build.public }, bs.reload)
  73. bs.init({
  74. notify: false,
  75. // files: 'dist/**',
  76. port: 3080,
  77. // open: false,
  78. server: {
  79. baseDir: [config.build.temp, config.build.src, config.build.public],
  80. routes: {
  81. '/node_modules': 'node_modules'
  82. }
  83. }
  84. })
  85. }

封装 Gulp-CLI

  1. 在之前的 demo 中,gulpfile 文件的作用就是引入模块提供的任务,显得比较冗余。可以通过在模块中添加 cli ,把 gulp 封装到模块中。在模块根目录添加 bin 目录,bin 目录下添加一个 cli 入口文件,在 package.json 中添加 bin 字段,bin 字段值就是入口文件。 <br />![image.png](https://cdn.nlark.com/yuque/0/2021/png/21429065/1625325795885-21532acc-b93b-4121-a70c-9c7a6ee108c9.png#clientId=u868f99e8-75c5-4&from=paste&height=68&id=u2919865a&margin=%5Bobject%20Object%5D&name=image.png&originHeight=83&originWidth=243&originalType=binary&ratio=1&size=3612&status=done&style=none&taskId=ue8b4c6d1-2103-4a85-85b1-e477f8ef819&width=198.5)
  1. "bin": "bin/chen-page.js",

cli 入口文件的内容:

  1. #!/usr/bin/env node
  2. // 拼接命令行参数
  3. process.argv.push('--cwd') // 指定工作目录
  4. process.argv.push(process.cwd()) // 当前目录
  5. process.argv.push('--gulpfile') //指定 gulpfile 文件
  6. process.argv.push(require.resolve('..')) //这里可以写成 ../lib/index.js,简写成 .. 会去查找 package.json 中的 main 字段
  7. // console.log(process.argv);
  8. require('gulp/bin/gulp') // 执行 gulp 模块的 gulp 文件

发布并使用模块

  1. yarn publish --registry https://registry.yarnpkg.com // 发布
  2. yarn add chen-pages --dev // 安装