一次通过gulp打包项目的实践

229 阅读3分钟

最近终于忍受不了每次维护一个thinkphp的前后端不分离的项目了,项目测试线没有连到git,而且项目中的css、js文件也没有压缩处理...问题很多,但是能跑就中🥹。

目前每次开发完成都要手动粘贴修改的文件,有时候可能都不知道改了哪些文件十分苦恼😖。正好最近想去优化另外一个项目,去了解了一下webpack打包,然后就🤔️,能不能给这个thinkphp项目也给安排上打包,然后通过shell脚本把打包的文件发到测试线。

然后就开始了我的第一次尝试。

首先思考🤔️,我需要做什么。

  1. 将css、js文件进行打包到指定目录,且相对原文件相对位置不变
  2. 将PHP文件、模板页面不进行处理,直接打包到指定目录

文件结构大致是这样

└── src
    ├── css
    │   ├── index.css
    │   └── other
    │       └── index.css
    ├── index.html
    ├── js
    │   ├── dev.js
    │   ├── test
    │   │   └── base.js
    │   └── test.js
    └── php
        ├── model
        │   └── demo.php
        └── test.php

目的有了,然后说干就干!

webpack

首先将js文件进行打包并放到相对位置,经过我的搜索找到了解决方案! 通过指定webpack多个entry就能解决,通过fs读取对应文件js路径,然后设置output为[name].js,就解决了这个问题。

css文件怎么处理呢?通过查询最终只找到了mini-css-extract-plugin这个插件,但是好像是需要导入后才能打包css并且不能满足我的需求,css文件相对位置也不能改变,可能是我太菜了😭。也是这个原因导致我抛弃了webpack。

但是我还没到此结束,我又找webpack怎么将文件不打包直接移动到指定目录,找到了copy-webpack-plugin这个插件。使用起来也十分简单:只用指定from和to文件就行了。

new CopyWebpackPlugin({
  patterns: [
    { from: "php", to: "php" },
  ],
})

以下就是本次webpack实践的全部代码

const path = require("path");
const fs = require("fs");
const CopyWebpackPlugin = require('copy-webpack-plugin');
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
function getFilesAndFoldersInDir(path) {
  const items = fs.readdirSync(path);
  const result = [];
  items.forEach(item => {
    const itemPath = `${path}/${item}`;
    const stat = fs.statSync(itemPath);
    if (stat.isDirectory()) {
      let data = {
        // 文件夹
        type: 'file',
        name: item
      }
      let children = getFilesAndFoldersInDir(itemPath)
      children.forEach(item => {
        result.push({
          type: 'file',
          name: `${data.name}/${item.name}`
        })
      })
    } else {
      // 文件
      // if (/\.js$/.test(item)) {
        result.push({
          type: 'file',
          name: item
        });
      // }
    }
  });
  return result;
}
module.exports = {
  mode: "none",
  entry: () => {
    return new Promise((resolve, reject) => {
      const targetDir = ['./js']
      let entryObj = {};
      const list = getFilesAndFoldersInDir('./js')
      list.forEach((item) => {
        entryObj[item.name] = {
          import: `./js/${item.name}`,
          filename: `./js/${item.name}`,
        };
      });
      resolve(entryObj)
    })
  },
  output: {
    // path动态获取绝对路径
    path: path.resolve(__dirname, "dist"),
    filename: "[name].[ext]",
  },
  module: {
    rules: [
      {
        test: /\.css$/i,
        use: [
          {
            loader: MiniCssExtractPlugin.loader,
            options: {
              publicPath: '../'
            }
          },
          "css-loader"
        ]
      }
    ]
  },
  plugins: [
    new CopyWebpackPlugin({
      patterns: [
        { from: "php", to: "php" },
      ],
    }),
    new MiniCssExtractPlugin({
      filename: "[name].css"
    })
  ]
};

gulp

webpack走不通,我又去搜看看有什么解决方案。然后就看到了一个用gulp和webpack打包thinkphp的文章,给我了一部分参考,在这个项目中css能不能用gulp来打包,其他的用webpack打包,哈哈哈,毕竟webpack都搞了一部分了。项目啊,能跑就行。

然后问gpt怎么用gulp打包,我一看,哎,js好像打包好像也挺简单,然后就开始了我接下来的实践。

const gulp = require('gulp');
const uglify = require('gulp-uglify');
const cleanCSS = require('gulp-clean-css');
const rename = require('gulp-rename');
const concat = require('gulp-concat');

gulp.task('js', function() {
  return gulp.src('src/js/*.js')
    .pipe(concat('app.js'))
    .pipe(uglify())
    .pipe(rename({ suffix: '.min' }))
    .pipe(gulp.dest('dist/js'));
});

gulp.task('css', function() {
  return gulp.src('src/css/*.css')
    .pipe(concat('styles.css'))
    .pipe(cleanCSS())
    .pipe(rename({ suffix: '.min' }))
    .pipe(gulp.dest('dist/css'));
});

gulp.task('default', gulp.parallel('js', 'css'));

随意的改改,然后搜了一下怎么过滤gulp.src的文件,找到了gulp-filter插件,不过gulp-filter的最新版本好像用了esmodule,我在网上找的都是commonjs,然后就安装了个7.0.0版本的,就能直接用了。filter中的数组名前面写!,就是不需要打包的文件,如果需要打包以.开头的文件,第二个参数上配置dot: true就能打包进去了。

下面就是本次gulp打包thinkphp项目的一次实践。

const gulp = require('gulp');
const uglify = require('gulp-uglify');
const cleanCSS = require('gulp-clean-css');
const filter = require('gulp-filter')

gulp.task('js', function() {
  return gulp.src('src/js/*.js')
    .pipe(uglify())
    .pipe(gulp.dest('dist/js'));
});

gulp.task('css', function() {
  return gulp.src(['src/css/**/*.css'])
    .pipe(cleanCSS())
    .pipe(gulp.dest('dist/css'));
});

gulp.task('base', function () {
  return gulp.src('src/**/*')
  .pipe(filter(['./src/php/**/*', './src/*'], {
    dot: true
  }))
  .pipe(gulp.dest('dist'))
})

gulp.task('default', gulp.parallel('js', 'css', 'base'));

总结

gpt真好用!!!