Introducing NPM and gulp to Manage Frontend Resources in a Django Project
Introduction I previously wrote an article “Asp-Net-Core Development Notes: Using NPM and gulp to Manage Frontend Static Files”. Now I'm developing a project with Django again. I previously put together a Django rapid-development scaffold “DjangoStarter”, so I might as well upgrade it~ I won't repeat myself about npm and gulp; the previous article already covered that. Let's get straight to the steps Installing Dependencies The steps for installing dependencies are the same as in the previous article, but here I'll just provide the package.json file. Copy it to the project root directory
目录5 个章节
Introduction
I previously wrote an article Asp-Net-Core Development Notes: Using NPM and gulp to Manage Frontend Static Files. Now I'm developing a project with Django again. I previously put together a Django rapid-development scaffold DjangoStarter, so I might as well upgrade it~
I won't repeat myself about npm and gulp; the previous article already covered that. Let's get straight to the steps
Installing Dependencies
The steps for installing dependencies are the same as in the previous article, but here I'll just provide the package.json file. Copy it into the project root directory, then run the command to install the dependencies.
The package.json file is as follows:
{
"name": "django_starter",
"version": "1.0.0",
"description": "",
"main": "index.js",
"repository": "https://github.com/Deali-Axy/DjangoStarter",
"author": "DealiAxy",
"license": "Apache License 2.0",
"dependencies": {
"bootstrap": "^5.1.3",
},
"devDependencies": {
"gulp": "^4.0.2",
"gulp-changed": "^4.0.3",
"gulp-clean-css": "^4.3.0",
"gulp-concat": "^2.6.1",
"gulp-rename": "^2.0.0",
"gulp-uglify": "^3.0.2",
"rimraf": "^3.0.2"
}
}
Run the command:
npm install
# 或者有安装yarn的话可以
yarn
gulp Configuration
Create a gulpfile.js file in the project root directory
Here's the configuration file:
/// <binding BeforeBuild='min' Clean='clean' ProjectOpened='auto' />
"use strict";
//加载使用到的 gulp 插件
const gulp = require("gulp"),
rimraf = require("rimraf"),
concat = require("gulp-concat"),
cssmin = require("gulp-clean-css"),
rename = require("gulp-rename"),
uglify = require("gulp-uglify"),
changed = require("gulp-changed");
//定义 static 下的各文件存放路径
const paths = {
root: "./static/",
css: './static/css/',
js: './static/js/',
lib: './static/lib/'
};
//css
paths.cssDist = paths.css + "**/*.css";//匹配所有 css 的文件所在路径
paths.minCssDist = paths.css + "**/*.min.css";//匹配所有 css 对应压缩后的文件所在路径
paths.concatCssDist = paths.css + "app.min.css";//将所有的 css 压缩到一个 css 文件后的路径
//js
paths.jsDist = paths.js + "**/*.js";//匹配所有 js 的文件所在路径
paths.minJsDist = paths.js + "**/*.min.js";//匹配所有 js 对应压缩后的文件所在路径
paths.concatJsDist = paths.js + "app.min.js";//将所有的 js 压缩到一个 js 文件后的路径
//使用 npm 下载的前端组件包
const libs = [
{name: "bootstrap", dist: "./node_modules/bootstrap/dist/**/*.*"},
];
// 使用 npm 下载的前端组件,自定义存放位置
const customLibs = [
// {name: 'font-awesome', dist: './node_modules/@fortawesome/fontawesome-free/**/*.*'},
]
//清除压缩后的文件
gulp.task("clean:css", done => rimraf(paths.minCssDist, done));
gulp.task("clean:js", done => rimraf(paths.minJsDist, done));
gulp.task("clean", gulp.series(["clean:js", "clean:css"]));
//移动 npm 下载的前端组件包到 wwwroot 路径下
gulp.task("move:dist", done => {
libs.forEach(item => {
gulp.src(item.dist)
.pipe(gulp.dest(paths.lib + item.name + "/dist"));
});
done()
})
gulp.task("move:custom", done => {
customLibs.forEach(item => {
gulp.src(item.dist)
.pipe(gulp.dest(paths.lib + item.name))
})
done()
})
//每一个 css 文件压缩到对应的 min.css
gulp.task("min:css", () => {
return gulp.src([paths.cssDist, "!" + paths.minCssDist], {base: "."})
.pipe(rename({suffix: '.min'}))
.pipe(changed('.'))
.pipe(cssmin())
.pipe(gulp.dest('.'));
});
//将所有的 css 文件合并打包压缩到 app.min.css 中
gulp.task("concat:css", () => {
return gulp.src([paths.cssDist, "!" + paths.minCssDist], {base: "."})
.pipe(concat(paths.concatCssDist))
.pipe(changed('.'))
.pipe(cssmin())
.pipe(gulp.dest("."));
});
//每一个 js 文件压缩到对应的 min.js
gulp.task("min:js", () => {
return gulp.src([paths.jsDist, "!" + paths.minJsDist], {base: "."})
.pipe(rename({suffix: '.min'}))
.pipe(changed('.'))
.pipe(uglify())
.pipe(gulp.dest('.'));
});
//将所有的 js 文件合并打包压缩到 app.min.js 中
gulp.task("concat:js", () => {
return gulp.src([paths.jsDist, "!" + paths.minJsDist], {base: "."})
.pipe(concat(paths.concatJsDist))
.pipe(changed('.'))
.pipe(uglify())
.pipe(gulp.dest("."));
});
gulp.task('move', gulp.series(['move:dist', 'move:custom']))
gulp.task("min", gulp.series(["min:js", "min:css"]))
gulp.task("concat", gulp.series(["concat:js", "concat:css"]))
//监听文件变化后自动执行
gulp.task("auto", () => {
gulp.watch(paths.css, gulp.series(["min:css", "concat:css"]));
gulp.watch(paths.js, gulp.series(["min:js", "concat:js"]));
});
Just mindlessly copy and paste it. When you actually use it, you only need to pay attention to these two snippets
//使用 npm 下载的前端组件包
const libs = [
{name: "bootstrap", dist: "./node_modules/bootstrap/dist/**/*.*"},
];
// 使用 npm 下载的前端组件,自定义存放位置
const customLibs = [
// {name: 'font-awesome', dist: './node_modules/@fortawesome/fontawesome-free/**/*.*'},
]
The first snippet is for relatively standard npm packages whose resource files are all under the dist directory. The configuration is fairly simple: just copy them as-is into our project's /static/lib directory. (Generally, relatively new npm packages all have this structure.)
The second snippet is for npm packages that don't follow the convention. By habit, we place the package's css and js files separately under the /static/lib directory. Of course, you can decide how to place them yourself; these rule configurations are quite flexible.
For example:
const customLibs = [
{name: 'example-lib/css', dist: './node_modules/example-lib/a/b/*.css'},
{name: 'example-lib/js', dist: './node_modules/example-lib/a/c/*.js'},
]
This way, you can copy the css files under the a/b directory and the js files under the a/c directory inside the example-lib package to the /static/lib/example-lib/css and /static/lib/example-lib/js directories in our project, respectively, which will make referencing them in the project more convenient later.
Running gulp Tasks
After configuration, just run this command:
gulp move
The gulp config above also includes many other tasks, but they don't feel very necessary. After all, this is a backend project, so just using the move command is enough.
For the other commands, you can check the previous article, which covers them in detail.
Referencing in the Project
This part is actually outside the scope of this article, but since I mentioned it, I'll write it down anyway.
In the template file, first load the static tag. At the beginning of the template code, write:
{% load static %}
Then, wherever you need to reference static files:
<link ref="stylesheet" href="{% static 'lib/bootstrap/dist/css/bootstrap.css' %}">
Because when we configured gulp earlier, we copied all npm packages into the /static/lib directory, references start with lib/.
_EOF_
Introducing NPM and gulp to Manage Frontend Resources in a Django Project
- 本文作者:
- 程序设计实验室
- 版权声明:
- 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
相关文章
Django-Filter介绍与刁钻需求的实现方法
Django-Filter是一个非常好用的第三方库,很好的利用了Django ORM的特性,可以使用很少的代码就扩展原有的接口,实现多种筛选功能~ 场景 Model定义的部分代码,可以看到需求模型包括了 关键词 keyword、区域 region、需求状态 require_status,这三个字段 class Require(models.Model): 需求 keyword =
2021-12-18 · Django · 约 1 分钟
性能提升4倍!使用Granian作为Django项目的ASGI服务器
Granian是Rust写的ASGI服务器,性能比Daphne强点,但离uWSGI还差着远?静态文件支持倒是省事。开发环境够用,生产环境还是得看情况。
2025-11-22 · Django · 约 1 分钟
实测 Django 6.0:模版片段、后台任务、CSP 安全,三大特性体验报告
呵,连WebSocket都没塞进去就敢叫大版本更新?不过模版片段和内置后台任务总算让Django像个现代框架了,至少写HTMX时不用再到处塞碎片文件。原生CSP?早该有了。至于抛弃Python 3.11——跟不上时代的版本留着也是累赘。
2026-01-20 · Django · 约 1 分钟
轻松搞定Django分页功能
view代码 from django.core.paginator import Paginator def announcement(request): ctx = { 'global': GlobalCtx, 'announcements': models.Announcement.objects.all(), } paginator
2022-05-27 · Django · 约 1 分钟
讨论
共 0 条加载评论中…