zoukankan      html  css  js  c++  java
  • Vue+Webpack+Grunt集成

    说明

    Vue、Grunt、Webpack的知识请看官方网站

    Grunt Tasks:构建、开发调试、打包,命令:grunt build,grunt default,grunt zipall。。。
    Webpack:编译Vue、压缩文件
    http2:启动http/2服务,命令  node http2.js
    server:启动http/1.x服务,命令:node server.js
    

    配置

    webpack.config.js

    var path = require('path')
    var webpack = require('webpack')
    module.exports = {
        entry: './src/main.js',
        output: {
            path: path.resolve(__dirname, './dist'),
            publicPath: '/dist/',
            filename: 'build.js',
            chunkFilename: "[id].build.js?[chunkhash]"  //vue-router异步加载组件,分包构建的文件命令规则
        },
        resolveLoader: {
            root: path.join(__dirname, 'node_modules')
        },
        module: {
            loaders: [
                {
                    test: /.vue$/,
                    loader: 'vue'
                },
                {
                    test: /.js$/,
                    loader: 'babel',
                    exclude: /node_modules/
                },
                {
                    test: /.css$/,
                    loader: 'style!css'
                },
                {
                    test: /.(eot|svg|ttf|woff|woff2)$/,
                    loader: 'file'
               },
                {
                    test: /.(png|jpg|gif|svg)$/,
                    loader: 'file',
                    query: {
                        name: '[name].[ext]?[hash]'
                    }
                }
            ]
        },
        devtool: '#eval-source-map',
        plugins:[]
    }
    

    GruntFile.js

    var webpack = require("webpack");
    var webpackconfig = require("./webpack.config.js");
    module.exports = function (grunt) {
        // 项目配置
        grunt.initConfig({
            pkg: grunt.file.readJSON('package.json'),
            clean: {
                build: {
                    src: ["dist/**/*","prod/**/*",'apistore.zip','dist.zip','html.zip']  //清空文件和文件夹
                }
            },
            webpack:{//调用webpack功能进行编译构建
                options: webpackconfig,
                prod:{//产品构建
                    devtool: '#source-map',
                    plugins: webpackconfig.plugins.concat(
                        new webpack.DefinePlugin({
                            'process.env': {
                                NODE_ENV: '"production"'
                            }
                        }),
                        new webpack.optimize.UglifyJsPlugin({
                            compress: {
                                warnings: false
                            }
                        })
                    )
                },
                dev:{//开发环境构建
                    devtool: '#eval-source-map',
                    plugins: webpackconfig.plugins.concat(
                        new webpack.optimize.DedupePlugin(),
                        new webpack.optimize.UglifyJsPlugin({
                            compress: {
                                warnings: false
                            }
                        })
                    )
                }
            },
            "webpack-dev-server":{//开发调试,实时编译
                options: {
                    webpack: webpackconfig,
                    publicPath: webpackconfig.output.publicPath
                },
                start: {
                    keepalive: true,
                    port:8086,
                    historyApiFallback: true,
                    noInfo: true,
                    inline:true,
                    hot:true,
                    compress: true,
                    watchOptions: {
                        aggregateTimeout: 300,
                        poll: 1000
                    }
                }
            },
            copy:{//拷贝文件
                common:{
                    files: [
                        {expand: true, src: ['package.json'], dest: 'prod/'},
                        {expand: true, src: ['index.html'], dest: 'prod/'},
                        {expand: true, src: ['dist/**/*'], dest: 'prod/'},
                    ]
                },
                http2:{
                    files: [
                        {expand: true, src: ['http2.js'], dest: 'prod/'},
                        {expand: true, src: ['ssl/**/*'], dest: 'prod/'}
                    ]
                },
                http:{
                    files: [
                        {expand: true, src: ['http.js'], dest: 'prod/'},
                        {expand: true, src: ['mine.js'], dest: 'prod/'},
                        {expand: true, src: ['server.js'], dest: 'prod/'}
                    ]
                }
            },
            zip: {//打zip包
                apistore:{
                    dest:'apistore.zip',src:['prod/**/*']
                },
                dist:{
                    dest:'dist.zip',src:['dist/**/*']
                },
                html:{
                    dest:'html.zip',src:['dist/**/*.js','dist/**/*.css']
                }
            },
            shell: {//shell命令
                options: {
                    stderr: true
                },
                dev: {
                    command: 'npm run dev'
                }
            }
        });
        grunt.loadNpmTasks('grunt-contrib-requirejs');
        grunt.loadNpmTasks('grunt-webpack');
        grunt.loadNpmTasks('grunt-contrib-clean');
        grunt.loadNpmTasks('grunt-contrib-imagemin');
        grunt.loadNpmTasks('grunt-zip');
        grunt.loadNpmTasks('grunt-shell');
        grunt.loadNpmTasks('grunt-contrib-copy');
    
        grunt.registerTask('ziph2', ['clean','webpack:prod','copy:common','copy:http2','zip:apistore']);
        grunt.registerTask('ziphttp', ['clean','webpack:prod','copy:common','copy:http','zip:apistore']);
        grunt.registerTask('zipall', ['clean','webpack:prod','copy:common','copy:http','copy:http2','zip:apistore']);
        grunt.registerTask('build-dev', ['clean','webpack:dev']);
        grunt.registerTask('build', ['clean','webpack:prod']);
        grunt.registerTask('default', ["webpack-dev-server"]);
    }
    

    http2.js

    var http2 = require("http2"),
        url = require("url"),
        path = require("path"),
        fs = require("fs");
    var port = 9443
        ,indexFile = "/index.html";//端口号和主文件地址
    
    var options = {
        key: fs.readFileSync(__dirname + '/ssl/server.key.insecure'),
        cert: fs.readFileSync(__dirname + '/ssl/server.crt'),
        ca:  fs.readFileSync(__dirname + '/ssl/server.csr')
    };
    function app(request, response) {
        var uri = url.parse(request.url).pathname,
            filename = path.join(process.cwd(), uri);
        fs.exists(filename, function(exists) {
            if(!exists) {
                response.writeHead(404, {"Content-Type": "text/plain"});
                response.write("404 Not Found
    ");
                response.end();
                return;
            }
            if (fs.statSync(filename).isDirectory()) {
                fs.exists(filename + indexFile, function(exists){
                    if(exists) {
                        fs.readFile(filename + indexFile, "binary", loadFile);
                    } else {
                        var files = fs.readdirSync(filename);
                        var html = '';
                        var showslash = uri + '/';
                        for (var i=0; i< files.length; i++){
                            if(uri == '/') {showslash = '/';} else {showslash = uri + '/';}
                            html += '<div><a href="' + showslash + files[i] + '">' + files[i] + "</a></div>";
                        }
                        response.writeHead(200);
                        response.write(html);
                        response.end();
                    }
                });
            } else {
                fs.readFile(filename, "binary", loadFile);
            }
        });
        function loadFile(err, file) {
            if(err) {
                response.writeHead(500, {"Content-Type": "text/plain"});
                response.write(err + "
    ");
                response.end();
                return;
            }
            response.writeHead(200);
            response.write(file, "binary");
            response.end();
        }
    }
    var server = http2.createServer(options, app);
    server.listen(parseInt(port, 10));
    console.log("Static file server running at
      => https://localhost:" + port + "/
    CTRL + C to shutdown");
    

    server.js

    var resolve = require('path').resolve
        , join = require('path').join
        , exec = require('child_process').exec
        , connect = require('connect')
        , stylus = require('stylus')
        , jade = require('jade')
        , less = require('less-middleware')
        , url = require('url')
        ,compression = require('compression')
        ,bodyParser = require('body-parser')
        ,serveStatic = require('serve-static')
        ,serveIndex = require('serve-index')
        ,morgan = require('morgan')
        , fs = require('fs');
    var config = {
        auth:undefined,//<user>:<pass> specify basic auth credentials
        logs:true,//disable request logging
        format:"dev",//fmt specify the log format string
        favicon:undefined,//path serve the given favicon
        jade:true,//disable jade rendering
        less:true,//disable less css rendering
        cors:true,//allows cross origin access serving
        compress:true,//gzip or deflate the response
        exec:undefined,//execute command on each request
        hidden:true,//enable hidden file serving
        dirs:true,//disable directory serving
        icons:true,//disable icons
        stylus:true,//disable stylus rendering
        port:9449//
    }
    // path
    var path = resolve('.');
    // setup the server
    var server = connect();
    // basic auth
    if (config.auth) {
        var user = config.auth.split(':')[0];
        var pass = config.auth.split(':')[1];
        if (!user || !pass) throw new Error('user and pass required');
        server.use(connect.basicAuth(user, pass));
    }
    //
    server.use(bodyParser.urlencoded());
    // ignore favicon
    if(config.favicon){
        favicon = require('serve-favicon');
        server.use(favicon(__dirname + config.favicon));
    }
    // logger
    if (config.logs) server.use(morgan(config.format));
    // convert .styl to .css to trick stylus.middleware
    if (config.stylus) {
        server.use(function(req, res, next){
            req.url = req.url.replace(/.styl$/, '.css');
            next();
        });
    }
    // jade
    if (config.jade) {
        server.use(function(req, res, next){
            if (!req.url.match(/.jade$/)) return next();
            var file = join(path, url.parse(req.url).pathname);
            fs.readFile(file, 'utf8', function(err, str){
                if (err) return next(err);
                try {
                    var fn = jade.compile(str, { filename: file });
                    str = fn();
                    res.setHeader('Content-Type', 'text/html');
                    res.setHeader('Content-Length', Buffer.byteLength(str));
                    res.end(str);
                } catch (err) {
                    next(err);
                }
            });
        });
    }
    // stylus
    server.use(stylus.middleware({ src: path }));
    // less
    if (config.less) {
        server.use(less(path));
    }
    // CORS access for files
    if (config.cors) {
        server.use(function(req, res, next){
            res.setHeader('Access-Control-Allow-Origin', '*');
            res.setHeader('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE,OPTIONS');
            res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization, Content-Length, X-Requested-With, Accept, x-csrf-token, origin');
            if ('OPTIONS' == req.method) return res.end();
            next();
        });
    }
    // compression
    if (config.compress) {
        server.use(compression());
    }
    // exec command
    if (config.exec) {
        server.use(function (req, res, next){
            exec(program.exec, next);
        });
    }
    // static files
    server.use(serveStatic(path, {
        maxAge: '1d',
        index: ['index.html'],
        //setHeaders: setCustomCacheControl,
        hidden: config.hidden
    }))
    // directory serving
    if (config.dirs) {
        server.use(path,serveIndex(path, {
            hidden: config.hidden
            , icons: config.icons
        }));
    }
    // start the server
    server.listen(config.port, function () {
        console.log('33[90mserving 33[36m%s33[90m on port 33[96m%d33[0m', path, config.port);
    });
    

    package.json

    {
      "name": "apistore",
      "description": "interferce project",
      "private": true,
      "scripts": {
        "dev": "cross-env NODE_ENV=development webpack-dev-server --config ./webpack.dev.config.js  --inline --hot --port 8086",
        "build": "cross-env NODE_ENV=production webpack --config ./webpack.prod.config.js --progress --hide-modules",
        "serve": "node server.js",
        "http2": "node http2.js"
      },
      "dependencies": {
        "element-ui": "^1.0.0",
        "vue": "^2.1.4",
        "vue-router":"^2.1.1",
        "http2":"^3.3.6",
        "http2-static-server":"^1.0.0",
        "serve": "^1.4.0",
        "path":"0.12.7",
        "http":"0.0.0",
        "connect": "3.5.0",
        "jade": "*",
        "less-middleware": "*",
        "stylus": "*",
        "serve-favicon":"2.3.2",
        "compression":"1.6.2",
        "body-parser":"1.15.2",
        "serve-static":"1.11.1",
        "serve-index":"1.8.0",
        "morgan":"1.7.0"
      },
      "devDependencies": {
        "babel-core": "^6.0.0",
        "babel-loader": "^6.0.0",
        "babel-preset-es2015": "^6.13.2",
        "cross-env": "^1.0.6",
        "css-loader": "^0.23.1",
        "file-loader": "^0.8.5",
        "style-loader": "^0.13.1",
        "vue-loader": "^9.5.1",
        "webpack": "2.1.0-beta.22",
        "webpack-dev-server": "^2.1.0-beta.0",
        "path":"0.12.7",
        "serve": "^1.4.0",
        "mockjs":"^1.0.1-beta3",
        "grunt-contrib-copy":"^1.0.0",
        "grunt-zip":"^0.17.1",
        "grunt-contrib-imagemin":"^1.0.1",
        "grunt-contrib-clean":"^1.0.0",
        "grunt-contrib-requirejs":"^1.0.0",
        "grunt-webpack":"^1.0.18",
        "http2":"^3.3.6",
        "http2-static-server":"^1.0.0",
        "grunt":"^1.0.1",
        "grunt-contrib-watch":"^1.0.0",
        "grunt-shell":"^2.1.0"
      }
    }
  • 相关阅读:
    2018.08.02
    加油。
    2018.07.08
    2018.06.22
    LeetCode #169. Majority Element 数组 摩尔投票法
    LeetCode #119 Pascal's Triangle II 数组 滚动数组
    LeetCode #845 Longest Mountain in Array 数组 线性DP
    LeetCode #41 First Missing Positive 数组
    LeetCode #384 Shuffle an Array 数组 洗牌算法
    LeetCode #189 Rotate Array 数组 双变量 双指针
  • 原文地址:https://www.cnblogs.com/TomSnail/p/6187049.html
Copyright © 2011-2022 走看看