commit 9d32fc9a9b4383634392368f213fdc553290272c Author: zenghuanyu Date: Tue Apr 2 17:38:33 2024 +0800 上传文件至 / diff --git a/README.md b/README.md new file mode 100644 index 0000000..50883ff --- /dev/null +++ b/README.md @@ -0,0 +1,37 @@ +## 简介 + +采用 Gulp 4.0.2 搭建的 js 自动构建任务项目 + +## 安装使用 + +请先安装**Node 14 和 Npm**,安装过程略过。 + +- 安装依赖 + +```bash +npm i +``` + +- 运行 + +```bash +npm run dev +``` + +- 打包 + +```bash +npm run build +``` + +## 目录介绍 + +- dist:打包结果目录 +- src:源码目录 +- src/modules:公共 html 目录,此目录的 html 不会出现在打包结果中,此目录的 html 中引入 css 或者 js,请使用绝对路径,如/js/xxx.js /css/xxx.css,其他资源,如图片也是如此 +- src/css:css 源码 +- src/js:js 源码 +- src/static:静态文件,如第三方库,第三方样式等可以放在此处,打包时不会进入文件转换流程,会直接复制到打包结果中 +- src/index.html:网站入口 +- config.js:打包配置 +- gulpfile.js:gulp 构建流程 diff --git a/config.js b/config.js new file mode 100644 index 0000000..99c4fff --- /dev/null +++ b/config.js @@ -0,0 +1,31 @@ +export default { + // 用于代码替换,key为文件id,value内容所在文件路径,为绝对路径,/为根目录 + // 在html中使用#include函数引入,如#include(navbar) + moduleMap: { + 'navbar': '/src/modules/navbar.html', + "footer": '/src/modules/footer.html', + }, + assetsDir: "dist", + devServer: { + // 详情配置请看 https://www.npmjs.com/package/http-proxy-middleware#options + httpProxy: { + // "/api": { + // target: '', // 替换为你的后端服务器地址 + // changeOrigin: true, // 如果需要的话,改变请求的origin + // pathRewrite: { + // '^/api': '' // 移除请求中的/api前缀 + // }, + // logLevel: "debug" + // } + }, + // 详情配置请看 https://browsersync.io/docs/options#option-server middleware和server不可配置 + browsersync: { + host: 'localhost', + port: 3000, + open: true, + ui: { + port: 3001 + } + } + } +} diff --git a/gulpfile.js b/gulpfile.js new file mode 100644 index 0000000..19cd52e --- /dev/null +++ b/gulpfile.js @@ -0,0 +1,273 @@ +import gulp from "gulp"; +import gulpIf from "gulp-if"; +import MemoryFS from "memory-fs"; +import syncBrowser from "browser-sync"; +const browserSync = syncBrowser.create(); +const __dirname = process.cwd(); + +// 创建内存文件系统实例 +const mfs = new MemoryFS(); +import htmlmin from "gulp-htmlmin"; // 压缩html文件 +import uglify from "gulp-uglify"; // 压缩js文件 +import babel from "gulp-babel"; // ES6转ES5 +import sass from "gulp-sass"; // sass编译 +import cleanCss from "gulp-clean-css"; // 压缩css文件 +import replace from "gulp-replace"; // 替换文件内容 +import ignore from "gulp-ignore"; // 排除文件不进入打包结果 +import { deleteAsync } from "del"; // 清除打包目标目录 +import fs from "fs/promises"; +import path from "path"; +import map from "map-stream"; +import { createProxyMiddleware } from "http-proxy-middleware"; + +const devAssetsDir = "src"; +const htmlGlob = `${devAssetsDir}/**/*.html`; +const cssGlob = `${devAssetsDir}/**/*.css`; +const jsGlob = `${devAssetsDir}/**/*.js`; +const staticGlob = `${devAssetsDir}/static/**/*`; +const modulesGlob = "modules/**/*"; +const allFileGlob = `${devAssetsDir}/**/*`; + +/** + * @type {"dev" | "prod"} 环境变量 + */ +let env = "dev"; +function setEnv(currEnv) { + return async () => { + env = currEnv; + }; +} +import config from "./config.js"; +let { moduleMap, assetsDir, devServer } = config; +let { browsersync: browsersyncOptions, httpProxy } = devServer && typeof devServer === "object" ? devServer : {}; +moduleMap = parseModuleMap(moduleMap); +// 异步读取文件内容 +async function getCode(path) { + return await fs.readFile(path, "utf8"); +} + +// 清除dist目录的任务 +async function cleanTask() { + return deleteAsync([assetsDir]); // 使用 del 删除 dist 目录及其内容 +} + +export const clean = cleanTask; + +/** + * @description 注入模块 + * @param {NodeJS.ReadWriteStream} ctx + * @returns {NodeJS.ReadWriteStream} + */ +async function injectModules(ctx) { + // 遍历模块文件,将每个模块文件的内容替换到对应的模块标签中 + for (const key in moduleMap) { + const filePath = path.join(__dirname, moduleMap[key]); + const code = await getCode(filePath); + const replaceStream = replace(key, code); + ctx = ctx.pipe(replaceStream); + } + return ctx; +} + +// 制定html任务 +async function htmlTask() { + const condition = env === "prod"; + let ctx = gulp.src(htmlGlob, { + ignore: [staticGlob], + }); + ctx = await injectModules(ctx); + return ( + ctx + .pipe( + htmlmin({ + removeComments: condition, // 生产环境下移除注释 + collapseWhitespace: condition, // //压缩HTML + collapseBooleanAttributes: condition, //省略布尔属性的值 ==> + removeEmptyAttributes: env === "prod", //删除所有空格作属性值 ==> + removeScriptTypeAttributes: false, //删除