This is the 21st day of my participation in Gwen Challenge
preface
In the previous article, gulp (7) : Using Babel translatorjs, I introduced how to use Babel translatorjs.
We all know that sometimes programs have multiple environments, such as a development environment and a release environment. In this article, you will learn how to isolate the environment in gulP projects.
The environment variable
NODE_ENV is a variable that can be used to differentiate the environment of a front-end Node project, so we need to change the value of this variable at startup or package time to make changes based on this variable.
NODE_ENV is also covered in the “environment variable NODE_ENV” section of my webPackage 5 series. In this article, I will briefly cover NODE_ENV.
On the Windows command line, we can use the set command to set environment variables. On the Linux command line, you need to use the export command to set environment variables. It is recommended to use the cross-env plugin to set environment variables uniformly, regardless of the system.
Installation of cross – env
npm i -D cross-env
Copy the code
Modify the scripts of package.json in the project.
{..."scripts": {..."build": "cross-env NODE_ENV=production gulp build"."dev": "cross-env NODE_ENV=development gulp"},... }Copy the code
We write the test code in gulpfile.js.
console.log('Environment variable:' + process.env.NODE_ENV)
Copy the code
Run NPM run build and you can see the following output from the terminal.
NODE_ENV=production of the build command works.
The separation of the environment
Separate the gulpfile.js configuration
In fact, gulpfile.js generally does not require environment separation, unlike webPack configuration, because it is task-specific and can be combined at will, as shown here with two exports separating development and production.
// Run gulp, which is the development environment
exports.default = series(clean, html, libJs, js, css, scss, libCss, img, devServer, watcher)
// Run build, which is the production environment
exports.build = series(clean, html, libJs, js, css, scss, libCss, img)
Copy the code
But what happens when gulpfile.js is overconfigured? We should split each small task or series of tasks (e.g., tasks that deal specifically with JS) into individual files and import these files in gulpfile.js to invoke the tasks inside.
Take the JS series of tasks as an example.
Start by creating a gulpfile-js.js file in the root directory to store JS-related tasks.
const { src, dest } = require('gulp')
const webpack = require('webpack-stream')
const webpackConfig = require("./webpack.config.js")
const named = require('vinyl-named')
const path = require('path')
const plumber = require('gulp-plumber')
const changed = require('gulp-changed')
const uglify = require('gulp-uglify')
function js() {
return src(['src/js/**/*.js'])
.pipe(changed('dist/js/**/'))
// .pipe(babel({
// presets: ['@babel/env'],
// plugins: ['@babel/transform-runtime']
// }))
.pipe(named(function (file) {
return file.relative.slice(0, -path.extname(file.path).length)
}))
.pipe(webpack(webpackConfig))
.pipe(plumber())
.pipe(uglify())
.pipe(dest('dist/js'))}function libJs() {
return src(['src/lib/**/*.js'])
.pipe(changed('dist/lib/**/'))
.pipe(plumber())
.pipe(dest('dist/lib'))}module.exports = {
js, libJs
}
Copy the code
Then, modify gulpfile.js to comment out the jS-related tasks and import the previous gulpfile-js.js file
const { js, libJs } = require('./gulpfile-js')
Copy the code
If you run NPM run build, you can find that the JS task is successfully executed.
Of course, this approach has its own disadvantages. It splits tasks into different files on a task basis, rather than creating different tasks on an environment basis. This may cause it to be difficult to discriminate between different environments within the same task. Or you can create a new task.
If you don’t like the idea of “assembling tasks” to separate the environment and want to have a clear separation of the environment, you can also create two files in the root directory with clear separation of the environment: Gulpfile.dev. Js and gulpfile.prod.js, and then export and import the relevant files in gulpfile.js as shown above.
Separate webpack configuration from webpack-stream
I in the article webpack5 use (two) : multiple environment configuration has been very detailed introduction of webpack configuration separation, have the need to partners can refer to this article.
Change the program based on the NODE_ENV variable
Sometimes, we may have some special requirements, such as not only “development environment” and “production”, may also have a “demo environment”, and “demo environment” it may need to replace some of web text, style or logic, equivalent to the original foundation of the program put a layer of skin.
At this point, what to do?
Now we can use the environment variable NODE_ENV.
We create a config.js in the root directory, which is the variable used to receive the command, and produce more variables based on the variables, such as: In a production environment, the header of the home page would be red and the foot would be yellow, so we would create these two variables and then use the plugin to change the color based on these variables.
Pseudo code
if (process.env.NODE_ENV == 'production') {
header = red
footer = yellow
}
Copy the code
Of course, you don’t have to do this, you can change the color directly in the business code based on the variable.
We write the following code in config.js.
const CONFIG = {}
CONFIG.ENV = process.env.NODE_ENV
module.exports = CONFIG
Copy the code
Note: For convenience, the attribute name exposed here is ENV, not NODE_ENV.
Import config.js in gulpfile.js.
const config = require('./config.js')
Copy the code
Change the HTML
Gulp-preprocess is a pre-processed HTML plug-in that can inject HTML code before the program is run or packaged.
The installation
npm i -D gulp-preprocess
Copy the code
Modify gulpfile.js configuration to introduce gulp-preprocess.
const preprocess = require("gulp-preprocess")...function html() {
return src(['src/**/*.html'.'! src/include/**.html'])
.pipe(changed('dist'))
.pipe(plumber())
.pipe(fileinclude({
prefix: '@ @'.// Reference symbol
basepath: './src/include'.// Reference the file path
}))
.pipe(preprocess({
context: { ...config }
}))
.pipe(htmlmin({
removeComments: true.// Clear HTML comments
collapseWhitespace: true.HTML / / compression
collapseBooleanAttributes: true.// Omit Boolean values ==>
removeEmptyAttributes: true. ==>
removeScriptTypeAttributes: true.// Delete
removeStyleLinkTypeAttributes: true.// Delete
minifyJS: true.// Compress the page JS
minifyCSS: true // Compress the page CSS
}))
.pipe(dest('dist'))}Copy the code
In the preprocess context above, we pass in a JSON object. The variables of this JSON object are imported into the HTML. Here we use es6’s object structure to assign all the properties of the Config object to the context.
At this point, we can use HTML variables. In index.html, we say the following
<! -- @if ENV = 'production' -->
<div><! -- @echo ENV --></div>
<! -- @endif -->
Copy the code
— @echo ENV –> outputs the ENV variable value “production”.
Note:
- Here,
<! -- -->
Comments are added, not removed, and the preprocessor automatically matches such code. @if
Be equal to, be equal to=
There is only one equal sign! =
.
Running NPM run build, we can look at dist/index.html and see
.
Dist /index.html is absent from NPM run dev.
Change the js
Unfortunately, there seems to be no plugin for gulp that can change JS. The documentation for gulp-preprocess does mention that it can be used on JS, but after my tests, I found that it does not work. If you have ideas, you can check the relevant documentation.
Of course, you can use process.env.node_env directly in js, but the config.js file you wrote earlier will not make any sense.
If your gulp project is useful for webpack-stream, you can install a webpack preprocess-loader that emulates gulp-preprocess. It just seems to work only with JS.
The installation
npm i -D preprocess-loader
Copy the code
Configure it in webpack.config.js
const config = require('./config')...module: {
module: {
rules: [{...test: /\.js$/,
exclude: /(node_modules|bower_components)/,
use: [
{
loader: 'preprocess-loader'.options: {
// Fill in the variables. config,ppOptions: {
type: 'js'}}}]},... }Copy the code
In the same way, config.js is introduced and takes advantage of es6 deconstruction.
In SRC /index.js, write the test code.
const env = '/* @echo ENV */'
if (env == 'production') {
console.log(env)
}
Copy the code
Run NPM run build, open dist/index.html, open the browser console, and you can see that “production” is printed.
Change the SCSS
We all know that SCSS has variables. Now we need to change the values of these SCSS variables according to the environment. The gulp-Sass-variables plugin can do this.
The installation
npm i -D gulp-sass-variables
Copy the code
We assume that the CDN address needs to be changed according to the environment, using the prefix http://2.com in the development environment and http://1.com in the production environment.
Let’s modify config.js
const CONFIG = {}
CONFIG.ENV = process.env.NODE_ENV
CONFIG.CDN = ' '
if (CONFIG.ENV == 'production') {
CONFIG.CDN = 'http://1.com'
} else {
CONFIG.CDN = 'http://2.com'
}
module.exports = CONFIG
Copy the code
Configuration gulpfile. Js
const sassVariables = require('gulp-sass-variables')
const config = require('./config.js')...function scss() {
return src(['src/scss/**/*.scss'])
.pipe(changed('dist/scss/**/'))
.pipe(plumber())
.pipe(sassVariables({
$CDN: config.CDN,
}))
.pipe(sass({ fiber }))
.pipe(cleanCss())
.pipe(dest('dist/scss'))}Copy the code
Note that you can’t use es6 deconstruction here, because SCSS variables are specified to have variable names prefixed with $.
Let’s modify the SRC/SCSS /index.scss file.
html {
body {
// background: blanchedalmond;
background: url(#{$CDN}/simao.jpg); }}Copy the code
The above uses #{$CDN} to introduce the CDN variable.
Run NPM run build, you can find that dist/ SCSS /index. SCSS file writes corresponding CDN address.
Complete the project
On August 30, 2021, I reorganized the project and put it on Gitee. You can clone it and use it directly. The code submission record sequence is consistent with the sequence of my series of articles.
Gitee Library link: gitee.com/only1zhuo/g…
“The Use of GULP” series
- Use of GULP (1) : Start (juejin. Cn)
- Using gulp (2) : HTML (juejin. Cn)
- Using gulp (3) : processing js (juejin. Cn)
- Using gulp (4) : Handling CSS (juejin.cn)
- Use of gulp (5) : processing images (juejin. Cn)
- Use of Gulp (6) : Using Webpack stream modularization (juejin. Cn)
- Using gulp (7) : Using Babel to translate JS (juejin.cn)
- Use of GULP (8) : Separation environment (juejin. Cn)