Vue、Grunt、Webpack的知識請看官方網站css
Grunt Tasks:構建、開發調試、打包,命令:grunt build,grunt default,grunt zipall。。。 Webpack:編譯Vue、壓縮文件 http2:啓動http/2服務,命令 node http2.js server:啓動http/1.x服務,命令:node server.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:[] }
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"]); }
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\n"); 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 + "\n"); 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\n => https://localhost:" + port + "/\nCTRL + C to shutdown");
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('\033[90mserving \033[36m%s\033[90m on port \033[96m%d\033[0m', path, config.port); });
{ "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" } }