一: 前端工程化的价值
工程化不等于工具,它是为解决问题而提出的技术方案,工程化的核心是整体项目的规划或者架构,工具只是落地或者实现的手段.
- 传统语言或语法的弊端.
- 无法使用模块化,组件化.
- 重复的机械式工作.
- 依赖后端服务的支持.
- 代码风格统一,质量保证.
二: 使用Gulp完成项目的自动化构建
Gulp自动化构建包目录:
|-jrg-pages ————————————包文件夹
|-bin ——————————————包的入口文件夹
|-jrg-pages.js
|-lib ——————————————-自动化构建入口文件夹
|-index.js
|-package.json
|-yarn.lock
|-.gitignore
// 自动化构建目录 lib/index.js 代码
// 引入gulp相关模块
const {
src,
dest,
parallel,
series,
watch
} = require("gulp");
// 统一管理gulp插件
const loadPlugins = require("gulp-load-plugins");
const plugins = loadPlugins();
// 热更新
const browseSync = require("browser-sync");
const bs = browseSync.create();
const del = require("del");
// 获取命令行当前目录
const cwd = process.cwd();
/**
* 常用插件:
* gulp-sass
* gulp-babel @babel/core @babel/preset-env
* gulp-swig
* gulp-imagemin
* del
* gulp-load-plugins
* browser-sync
* gulp-useref
* gulp-htmlmin // 压缩html
* gulp-uglify // 压缩js
* gulp-if
* gulp-clean-css // 压缩css
*/
// 默认配置文件
let config = {
build: {
src: "src",
dist: "dist",
templates: "templates",
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 (error) {
console.log(error)
}
// 结构默认配置文件
const { build } = config;
const {
paths,
dist,
templates,
public
} = build;
const { styles, scripts, pages, images, fonts } = paths;
// 样式处理 任务
const style = () => {
return src(
styles,
{
sourcemaps: true,
base: build.src,
cwd: build.src
})
.pipe(plugins.sass({ outputStyle:"expanded" }))
.pipe(dest(templates))
.pipe(bs.reload({ stream: true }))
}
// js处理 任务
const script = () => {
return src(scripts, { base: build.src, cwd: build.src })
.pipe(plugins.babel({ presets: [require("@babel/preset-env")] }))
.pipe(dest(templates))
.pipe(bs.reload({ stream: true }))
}
// html文件处理 任务
const page = () => {
return src(pages, { base: build.src, cwd: build.src })
.pipe(plugins.swig({ data: config.data, defaults: { cache: false } }))
.pipe(dest(templates))
.pipe(bs.reload({ stream: true }))
}
// image, font, build下的文件,直接拷贝到dist目录,不用temp作为中转 任务
const image = () => {
return src(images, { base: build.src, cwd: build.src })
.pipe(plugins.imagemin())
.pipe(dest(dist))
}
// 字体文件处理 任务
const font = () => {
return src(fonts, { base: build.src, cwd: build.src })
.pipe(plugins.imagemin())
.pipe(dest(dist))
}
// public下的文件直接拷贝过去
const extra = () => {
return src(
"**",
{
base: public,
cwd: public
})
.pipe(dest(dist))
}
// 清除任务
const clean = () => {
return del([dist, templates]);
}
// 压缩处理任务
const useref = () => {
return src(
pages,
{
base: templates,
cwd: templates
})
.pipe(plugins.useref({ searchPath: [templates, "."] }))
// 压缩处理js, html, css
.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 serve = () => {
// 监听文件的变化, 两个参数,第一个参数是文件路径,第二个参数处理任务的函数
watch(styles,{ cwd: build.src }, style)
watch(scripts, { cwd: build.src }, script)
watch(pages,{ cwd: build.src }, page)
watch([
images,
fonts
], { cwd: build.src }, bs.reload)
watch("**",{ cwd: public }, bs.reload)
bs.init({
notify: false,
port: 8888,
server: {
baseDir: [templates, dist, public],
routes: {
"/node_modules": "node_modules"
}
}
})
}
// 编译任务
const compile = parallel(style, script, page);
// builds任务
const builds = series(
clean,
parallel(
series(compile, useref),
image,
font,
extra
)
);
// 本地开发任务
const dev = series(compile, serve)
module.exports = {
clean,
builds,
dev,
}
// bin/jrg-pages.js 文件代码
#!/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");
// package.json 说明
// 1: 插件都放入dependencies依赖中
// 2: 增加: "files": [ "lib", "bin" ],
// 3: 增加: "bin": "bin/jrg-pages.js",
// 4: 增加: "main": "lib/index.js",