nodejs自动构建项目结构

最近开发的宣传、落地、活动等单页较多,其项目结构和所需基本文件一致,html、css、js中基础的代码也一致

项目结构

例项目project

-project
    -projectSrc
        -css
            -reset.css
            -common.scss
        -img
        -js
            -jquery.js
            -common.js
    -project.html

reset.css

初始内容

/* reset */
html,body,h1,h2,h3,h4,h5,h6,div,dl,dt,dd,ul,ol,li,p,blockquote,pre,hr,figure,table,caption,th,td,form,fieldset,legend,input,button,textarea,menu{margin:0;padding:0;}
header,footer,section,article,aside,nav,hgroup,address,figure,figcaption,menu,details{display:block;}
table{border-collapse:collapse;border-spacing:0;}
caption,th{text-align:left;font-weight:normal;}
html,body,fieldset,img,iframe,abbr{border:0;}
i,cite,em,var,address,dfn{font-style:normal;}
[hidefocus],summary{outline:0;}
li{list-style:none;}
h1,h2,h3,h4,h5,h6,small{font-size:100%;}
sup,sub{font-size:83%;}
pre,code,kbd,samp{font-family:inherit;}
q:before,q:after{content:none;}
textarea{overflow:auto;resize:none;}
label,summary{cursor:default;}
a,button{cursor:pointer;}
h1,h2,h3,h4,h5,h6,em,strong,b{font-weight:bold;}
del,ins,u,s,a,a:hover{text-decoration:none;}
body,textarea,input,button,select,keygen,legend{font:12px/1.14 arial,\5b8b\4f53;color:#333;outline:0;}
body{background:#fff;}
a,a:hover{color:#333;}
.clear:after,.clearfix:after {display: block;content: "clear";height: 0;clear: both;overflow: hidden;visibility: hidden;}
.clear,.clearfix  {zoom: 1}

common.scss

初始内容

html{
    font-size: 20px;
}
* {
    box-sizing: border-box;
}
html,body{
    width: 100%;
    height: 100%;
}
.g-wrapper {
    position: relative;
    width: 100%;
    min-height: 100%;
    overflow-x: hidden;
    line-height: 1;
}

common.js

初始内容

    <!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <title></title>
        <meta name="viewport" content="width=device-width,height=device-height,initial-scale=1, maximum-scale=1">
        <meta name="apple-mobile-web-app-capable" content="yes">
        <meta name="apple-mobile-web-app-status-bar-style" content="black">
        <meta name="format-detection" content="telephone=no">
        <meta name="format-detection" content="email=no" />

        <link rel="stylesheet" href="{{path}}/css/reset.css" />
        <link rel="stylesheet" href="{{path}}/css/common.css" />
    </head>
    <body>
        <div class="g-wrapper">

        </div>

        <script type="text/javascript" src="{{path}}/js/jquery.js" ></script>
        <script type="text/javascript" src="{{path}}/js/common.js" ></script>
    </body>
</html>

可选loading

js中

//加载新css文件
var _getCss = function(href,callback){
    if ($("link[href='"+href+"']").length > 0) {
        callback();
        return;
    }
    var c = document.createElement("link");
    c.setAttribute("rel", "stylesheet");
    c.setAttribute("type", "text/css");
    c.setAttribute("href", href);
    document.getElementsByTagName("head")[0].appendChild(c);
    callback();
}
$.loading = {
    show: function(){
        _getCss("{{path}}Src/css/loading.css",function(){
            $('body').append(
                '<div class="preloader-overlay">'+
                    '<div class="preloader-indicator-modal">'+
                        '<span class="preloader"></span>'+
                    '</div>'+
                '</div>'
            );
        })
    },
    hide: function(){
        setTimeout(function(){
            $('body').find('.preloader-overlay').remove();
        },100)
    }
};

loading.css

.preloader-overlay {
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    z-index: 99999;
}
.preloader-indicator-modal {
    position: absolute;
    left: 50%;
    top: 50%;
    padding: 0.4rem;
    margin-left: -1.25rem;
    margin-top: -1.25rem;
    background: rgba(0,0,0,.8);
    z-index: 11000;
    border-radius: 0.25rem;
}
.preloader-indicator-modal .preloader {
    display: block;
    width: 1.7rem;
    height: 1.7rem;
}
.preloader {
    display: inline-block;
    width: 1rem;
    height: 1rem;
    -webkit-transform-origin: 50%;
    transform-origin: 50%;
    -webkit-animation: preloader-spin 1s steps(12,end) infinite;
    animation: preloader-spin 1s steps(12,end) infinite;
}
.preloader:after {
    display: block;
    content: "";
    width: 100%;
    height: 100%;
    background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg%20viewBox%3D'0%200%20120%20120'%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20xmlns%3Axlink%3D'http%3A%2F%2Fwww.w3.org%2F1999%2Fxlink'%3E%3Cdefs%3E%3Cline%20id%3D'l'%20x1%3D'60'%20x2%3D'60'%20y1%3D'7'%20y2%3D'27'%20stroke%3D'%23fff'%20stroke-width%3D'11'%20stroke-linecap%3D'round'%2F%3E%3C%2Fdefs%3E%3Cg%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(30%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(60%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(90%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(120%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(150%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.37'%20transform%3D'rotate(180%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.46'%20transform%3D'rotate(210%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.56'%20transform%3D'rotate(240%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.66'%20transform%3D'rotate(270%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.75'%20transform%3D'rotate(300%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.85'%20transform%3D'rotate(330%2060%2C60)'%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E");
    background-position: 50%;
    background-size: 100%;
    background-repeat: no-repeat;
}
@-webkit-keyframes preloader-spin {
    100% {
        -webkit-transform: rotate(360deg);
    }
}
@keyframes preloader-spin {
    100% {
        -webkit-transform: rotate(360deg);
        transform: rotate(360deg);
    }
}

nodejs

为减少创建文件的重复工作,简单的用node的fs模块代替人工步骤

var arguments = process.argv.splice(2);

if (arguments.length < 2) {
    console.log("缺少参数 arg1:项目名称 arg2:文件夹名称");
    return;
}


var oldSrc = "1插件/init/";

var project = arguments[0];
var path = arguments[1];
var loadingFlag = arguments[2];


var fs = require("fs");


if (fs.existsSync(`${project}/${path}/`)) {
    console.log("目录已存在");
    process.exit();
}


fs.mkdir(`${project}/${path}/`,function(){
    fs.mkdir(`${project}/${path}/${path}Src/`,function(){
        fs.mkdir(`${project}/${path}/${path}Src/css/`,function(){
            fs.createReadStream(`${oldSrc}reset.css`).pipe(fs.createWriteStream(`${project}/${path}/${path}Src/css/reset.css`));
            fs.createReadStream(`${oldSrc}common.scss`).pipe(fs.createWriteStream(`${project}/${path}/${path}Src/css/common.scss`));
            if (loadingFlag == "load") {
                fs.createReadStream(`${oldSrc}loading.css`).pipe(fs.createWriteStream(`${project}/${path}/${path}Src/css/loading.css`));
            }
        });
        fs.mkdir(`${project}/${path}/${path}Src/js/`,function(){
            fs.createReadStream(`${oldSrc}jquery.js`).pipe(fs.createWriteStream(`${project}/${path}/${path}Src/js/jquery.js`));
            var js = "";
            if (loadingFlag == "load") {
                var jsreadStream = fs.createReadStream(`${oldSrc}common-loading.js`);    
            }else{
                var jsreadStream = fs.createReadStream(`${oldSrc}common.js`);
            }
            var jswriterStream = fs.createWriteStream(`${project}/${path}/${path}Src/js/common.js`);
            jsreadStream.setEncoding('UTF8');
            jsreadStream.on('data', function(chunk) {
                var str = chunk;
                if (/{{path}}/.test(chunk)) {
                       var str = chunk.replace(/{{path}}/ig,path);
                }
                jswriterStream.write(str,'UTF8');
            });
        });
        fs.mkdir(`${project}/${path}/${path}Src/img/`);
    });


    var htmlStr = "";
    var readStream = fs.createReadStream(`${oldSrc}index.html`);
    var writerStream = fs.createWriteStream(`${project}/${path}/${path}.html`);
    readStream.setEncoding('UTF8');
    readStream.on('data', function(chunk) {
        var str = chunk;
        if (/{{path}}/.test(chunk)) {
               var str = chunk.replace(/{{path}}/ig,`${path}Src`);
        }
        writerStream.write(str,'UTF8')
    });

});

console.log("好像还没报错?");

配置可选项为

var oldSrc =  "初始文件路径"

调用方法为

node init @param @param @param

参数一:要创建项目的所属文件夹名
参数二:项目名称
参数三:值为load时加载调用load的函数和相应css

作用:

  • 按项目名称新建文件夹及复制文件
  • 替换html中的引用路径
  • 替换js中代码模块化的函数名称
坚持技术分享,您的支持将鼓励我继续创作!