使用gitLab建立npm公共组件

步骤如下:

  1. 在gitLab上建立一个项目,用于存放组件代码

  2. 项目代码
    npm init 初始化一个 package.json

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    {
    "name": "@wjs-npm/fixedHeaderTable", // 组件名称(建议使用 @库名/组件名 的写法)
    "version": "1.0.0", // 组件版本
    "private": true, // 防止代码被公开发布
    "description": "HelloWorld",
    "main": "index.js",
    "repository": {
    "type": "git",
    "url": "https://git.wjs-dev.com/wjs-npm/fixedHeaderTable.git"
    },
    "author": "bayunjiang",
    "license": "ISC"
    }

    新建一个 index.js 文件,在其中写一个示例函数,内容参考如下。

    1
    2
    3
    4
    5
    const HelloWorld = () => {
    console.log('Hello World')
    }

    export { HelloWorld }

    也可以写成vue插件,以自己写的一个插件为例。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    import ElTable from './ElTable'

    export default {
    install (Vue, options) {
    if (options) {
    ElTable.data = function () {
    return Object.assign({
    topOffset: 60,
    rightOffset: 12,
    tableWidth: 0,
    headerFixed: false
    }, options)
    }
    }
    Vue.component(ElTable.name, ElTable)
    }
    }
  3. 安装依赖
    使用npm安装依赖

    1
    npm install -S git+https://git.wjs-dev.com/wjs-npm/fixedHeaderTable.git

    默认安装的是 master 分支的代码
    安装完成之后我们可以在 package.json 文件中看到如下内容。

    1
    2
    3
    "dependencies": {
    "@wjs-npm/fixedHeaderTable": "git+https://git.wjs-dev.com/wjs-npm/fixedHeaderTable.git"
    }
  4. 插件使用
    和其它npm包的使用一样

    1
    2
    3
    4
    import Vue from 'Vue'
    import fixedHeaderTable from '@wjs-npm/fixedHeaderTable'

    Vue.use(fixedHeaderTable)
  5. 版本管理
    通过建立 tag 进行版本管理

    在安装依赖时,在原链接后面加上 #tag 设置版本

    1
    npm install -S git+https://git.wjs-dev.com/wjs-npm/fixedHeaderTable.git#1.0.0
  6. 存在的问题
    由于npm有缓存机制,所以下载一次后如果你更新了依赖代码,再次运行 npm install 是无法拉取到最新代码的。
    如果要更新依赖,需要删除重新安装。

手机共通问题

问题一:用同等比例的图片在PC机上很清楚,但是手机上很模糊,原因是什么呢?

经研究发现是devicePixelRatio作怪,因为手机分辨率太小,如果按照分辨率来显示网页字会非常小,所以苹果就把iPhone 4的960640分辨率在网页里只显示了480320,这样devicePixelRatio=2;现在android比较乱,有1.5/2/3等,想让图片在手机里显示更为清晰必须使用2x的背景图来代替img标签(一般情况都是用2倍),例如一个div的宽高是100100,背景图必须得200200,然后background-size:contain;,这样显示出来的图片就比较清晰了;代码如下:

1
2
3
4
5
6
background:url(../images/icon/all.png) no-repeat center center;
-webkit-background-size:50px 50px;
background-size: 50px 50px;
display:inline-block;
width:100%;
height:50px;
阅读全文 »

预加载资源,浏览器空闲的时候就会去加载

预解析DNS:

预建立TCP连接:

推荐使用浏览器内核,IE=edge告诉IE使用最新的引擎渲染网页,chrome=1则可以激活Chrome Frame

只允许加载自己域的图片:

会将网页的http请求强制升级为https:

禁止请求optionally-blockable(被动混淆资源,包括audio、favicon、image、vedio)

在https的网站请求http的内容就是Mixed Content(混淆资源),这种请求通常会被blocked(阻塞),因为http是没有加密的。而请求被动混淆资源(optionally-blockable)不会被阻塞

旋转效果(貌似已经失效)

快速转换通道:

http://www.useragentman.com/IETransformsTranslator/

代码:

filter:progid:DXImageTransform.Microsoft.Matrix(Dx=dx,Dy=dy,M11=m11,M12=m12,M21=m21,M22=m22);

算法:

dx=-width/2cos(deg)+height/2sin(deg)+width/2

dy=-width/2sin(deg)-height/2cos(deg)+height/2

设旋转角为x,用弧度表示。

m11=cos(x)

m12=-sin(x)

m21=sin(x)

m22=cos(x)

背景拉伸

代码:

filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src=’.bg.jpg’, sizingMethod=’scale’);

图片路径用绝对路径

背景色透明

代码:

filter: progid:DXImageTransform.Microsoft.gradient(startcolorstr=#4c20244d,endcolorstr=#4c20244d);

颜色前两位代表透明度

渐变

代码:

filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=#f5f5f5,endColorstr=#ffffff,GradientType=0);

GradientType: 0 垂直 1 水平

想要构建一个vue2的单页应用,发现vue-cli生成的项目虽然可以直接用,但是生成的项目是用的vue1,而且直接使用也不能完全掌握和了解项目用了哪些插件和打包工具,为了自己更好的了解和学习开发vue2需要用到的打包工具和相关插件,自己看了许多博客,总结了以下一个构建基本vue2单页项目的流程,对于vue2和webpack小白可以跟着步骤试着自己构建一个小项目,如有大神请多指教。

完整源码链接:https://github.com/chenjiaj/vue2-express4-webpack

一、环境

需要安装node v4.4.4及以上

二、创建基本项目

1.打开cmd,运行 npm install express-generator -g (express-generator是express的应用生成器,相关介绍:http://www.expressjs.com.cn/starter/generator.html

用生成器生成主要是为了使用bin文件夹下的www文件,为了少写一点打印的日志而已,对应不需要的,可以不用生成器生成,自己创建server就行,可以用http模块或者直接调用app.listen都可以

2.切换到你要生成项目的目录,然后运行 express myapp,生成新的express项目,目录如下:

Paste_Image.png

3.删除public、routes、views文件夹,现在项目目录如下

Paste_Image.png

4.在根目录下创建index.html,内容如下:

Title

5.在根目录下添加src文件,然后创建app.vue和main.js

app.vue的内容如下:

main.js的内容如下:

import Vue from “vue”;
import App from “./app”;
new Vue({
el:’#app’,
render:h=> h(App)
})

如果是用的webStorm,请将language设置为ECMAScript6,这样才不会报错误提示

Paste_Image.png

6.需要安装以下依赖,将package.json文件替换如下:

{ “name”: “myapp”,
“version”: “0.0.0”,
“private”: true,
“scripts”: { “start”: “node ./bin/www” },
“devDependencies”: {
“babel-core”: “^6.20.0”,
“babel-loader”: “^6.2.9”,
“babel-plugin-transform-runtime”: “^6.15.0”,
“babel-preset-es2015”: “^6.18.0”,
“babel-runtime”: “^5.8.38”,
“babel-preset-stage-2”: “^6.18.0”,
“html-webpack-plugin”: “^2.24.1”,
“vue-html-loader”: “^1.2.3”,
“css-loader”: “^0.26.1”,
“vue-loader”: “^10.0.2”,
“vue-template-compiler”: “^2.1.6”,
“webpack”: “^1.14.0”,
“webpack-dev-middleware”: “^1.6.1”
},
“dependencies”: {
“express”: “^4.14.0”,
“vue”: “^2.1.6”,
“vue-router”: “^2.1.1”
}
}

以babel-开头:都是用于兼容es6写法,将es6的代码转换成es5的代码

babel-core、babel-loader:babel配合webpack工具使用必须要引入的

babel-plugin-transform-runtime、babel-runtime:解决重复出现在一些模块里,导致编译后的代码体积变大的问题。

babel-preset-es2015:将 ES2015 编译成 ES5

babel-preset-stage-2:除了覆盖stage-3的所有功能,不是对ES6功能的增加,而是为了增强代码的可读性和可修改性而提出的

参考:http://babeljs.io/docs/setup/#installation

webpack :webpack打包需要引入的核心包

html-webpack-plugin:是webpack的插件,这个插件用来简化创建服务于 webpack bundle 的 HTML 文件,尤其是对于在文件名中包含了 hash 值,而这个值在每次编译的时候都发生变化的情况。你既可以让这个插件来帮助你自动生成 HTML 文件,也可以使用 lodash 模板加载生成的 bundles,或者自己加载这些 bundles。

vue-loader:是webpack的loader,能够将.vue文件转换成js文件

vue-html-loader、vue-template-compiler、css-loader:这三个都是webpack的loader,都是将.vue文件转换成js文件的依赖

webpack-dev-middleware :需要webpack打包的项目,开发时使用的中间件,主要作用是不需要将打包生成的文件放在硬盘中,而是放在内存中,这样可以提高开发效率,而且配合webpack-hot-middleware中间件使用可以实现热加载(热加载插件后面会介绍)

7.在根目录下添加build文件夹,在文件夹内创建webpack.base.conf.js,内容如下:

// nodejs 中的path模块
var path = require(‘path’);
var webpack = require(‘webpack’);
var HtmlWebpackPlugin = require(‘html-webpack-plugin’);
var webpackConf = {
// 入口文件,path.resolve()方法,可以结合我们给定的两个参数最后生成绝对路径,最终指向的就是我们的index.js文件
entry: { index: [ path.resolve(__dirname, ‘../src/main.js’) ] },
// 输出配置
output: { // 输出路径是 myProject/output/static
path: path.resolve(__dirname, ‘../output’),
publicPath:’/‘, filename: ‘[name].[hash].js’
},
resolve: {
extensions: [‘’, ‘.js’, ‘.vue’],
alias: { ‘vue’: ‘vue/dist/vue.js’ } // 设置别名vue1不需要设置,vue2必须设置 否则会报错
},
module: {
loaders: [
// 使用vue-loader 加载 .vue 结尾的文件
{ test: /.vue$/, loader: ‘vue’ },
{ test: /.js$/, loader: ‘babel’, exclude: /node_modules/ } ]
},
vue: { loaders: { js: ‘babel’ } },
plugins:[
new HtmlWebpackPlugin({
filename: ‘index.html’,
template: path.resolve(__dirname, ‘../index.html’),
inject: true
}) ]
};
module.exports = webpackConf;

path:用来存放打包后文件的输出目录

publicPath:指定资源文件引用的目录

8.将根目录下app.js内容替换如下:

var express = require(‘express’);
var path = require(‘path’);
var webpack = require(‘webpack’);
var webpackConfig = require(‘./build/webpack.base.conf’);
var app = express();// 创建一个express实例
var compiler = webpack(webpackConfig);// 调用webpack并把配置传递过去
// 使用 webpack-dev-middleware 中间件
var devMiddleware = require(‘webpack-dev-middleware’)(compiler, {
publicPath: ‘/‘,
stats: {
colors: true,
chunks: false
}});
app.use(devMiddleware);
module.exports = app;

10.在根目录下添加.babelrc文件,内容如下:

{ “presets”: [“es2015”,”stage-2”], “plugins”: [“transform-runtime”], “comments”: false}

presets 字段设定转码规则,官方提供以下的规则集,你可以根据需要安装。

comments是否输出输出中的注释

9.在根目录下运行 npm install ,然后运行npm start,webpack编译完之后如下图所示,就可以通过http://localhost:3000 访问了,效果如图所示:

Paste_Image.png

Paste_Image.png

这样就生成了一个简单的应用。

三、添加热加载

开发是需要热加载,即修改完代码后重新编译并更新浏览器,提高开发效率

热加载需要webpack-hot-middleware中间件(https://www.npmjs.com/package/webpack-hot-middleware)

1.在项目根目录下运行npm install –save-dev webpack-hot-middleware

2.打开app.js,添加app.use(require(“webpack-hot-middleware”)(compiler));

3.在webpack.base.conf.js中的plugins中添加

// Webpack 1.0
new webpack.optimize.OccurenceOrderPlugin(),
// Webpack 2.0 fixed this mispelling
// new webpack.optimize.OccurrenceOrderPlugin(),
new webpack.HotModuleReplacementPlugin(),
new webpack.NoErrorsPlugin()

方法一:只完成以下步骤4

4.在webpack.base.conf.js中添加以下代码:

Object.keys(webpackConf.entry).forEach(function (name) {
var extras = [‘webpack-hot-middleware/client?reload=1’];
webpackConf.entry[name] = extras.concat(webpackConf.entry[name]);
});

方法二:以下步骤4-6

4.在build文件夹中新建hot-client.js文件,内容如下:

// 动态向入口配置中注入 webpack-hot-middleware/client
var hotClient = require(‘webpack-hot-middleware/client’)
// 订阅事件,当 event.action === ‘reload’ 时执行页面刷新
hotClient.subscribe(function (event) {
if (event.action === ‘reload’) { window.location.reload() }
})

  1. 修改webpack.base.conf.js中的enter,改为以下代码:

entry: {
index: [
‘webpack-hot-middleware/client’,
path.resolve(__dirname, ‘../src/main.js’) ]
}

6.在webpack.base.conf.js中添加以下代码:

var hotClient = ‘./build/hot-client’;
Object.keys(webpackConf.entry).forEach(function (name) {
var extras = [hotClient];
webpackConf.entry[name] = extras.concat(webpackConf.entry[name]);
});

重新启动服务,修改vue或者js可以看到浏览器自动更新了

注意如果编辑器是webstorm的要将settings=>appearance=>system settings中synchronization中的最后一个选项不勾选,否则没有效果

Paste_Image.png

四、将开发的webpack配置提取出来

因为开发时需要webpack-dev-middleware、webpack-hot-middleware这两个中间件,但是正真发布的时候并不需要,因此需要将这两个的配置提取出来。

webpack-dev-middleware 这个中间件的作用是 开发的时候不生成代码,编译后的代码放在内存中,不会写入硬盘,因此不用每次编译都生成新的文件,提高开发效率

webpack-hot-middleware用于热加载,修改代码后立即更新

1.首先运行npm install –save-dev webpack-merge 下载 webpack-merge 工具,用于合并webpack配置使用

2.运行 npm install –save-dev cross-env 下载cross-env工具,用户在命令中设置环境变量

3.在build文件夹中新建webpack.dev.conf.js,写入以下代码:

var path = require(‘path’);
var webpack = require(‘webpack’);
var webPackBaseConf = require(‘./webpack.base.conf’);
var HtmlWebpackPlugin = require(‘html-webpack-plugin’);
var merge = require(‘webpack-merge’);
var hotClient = ‘./build/hot-client’;

var webpackDevConf = merge(webPackBaseConf,{
entry: { index: [ hotClient, path.resolve(__dirname, ‘../src/main.js’) ]},
plugins:[
// Webpack 1.0 new webpack.optimize.OccurenceOrderPlugin(),
// Webpack 2.0 fixed this mispelling
// new webpack.optimize.OccurrenceOrderPlugin(),
new webpack.HotModuleReplacementPlugin(),
new webpack.NoErrorsPlugin()
]});

Object.keys(webpackDevConf.entry).forEach(function (name) {
var extras = [hotClient];
webpackDevConf.entry[name] = extras.concat(webpackDevConf.entry[name]);
});
module.exports = webpackDevConf;

然后删除webpack.base.conf.js中对应的代码

注意删除的时候小心,不要将webpack.base.conf.js中的下面代码删掉了

plugins:[new HtmlWebpackPlugin({   
    filename: 'index.html',   
    template: path.resolve(__dirname, '../index.html'),   
    inject: true  }) 
]})]

4.修改package.json中script中start改为如下:

“start”: “cross-env NODE_ENV=development node bin/www”

运行这个命令会将环境变量设置为development(默认也是development ,但为了避免环境配置被修改的情况下可以手动设置一次)

5.修改app.js,添加环境变量判断,将开发使用的中间件添加到条件成立时执行,改为如下:

var express = require(‘express’);
var path = require(‘path’);
// 创建一个express实例
var app = express();
if(app.get(‘env’) == ‘development’){
var webpack = require(‘webpack’);
var webpackConfig = require(‘./build/webpack.dev.conf’);
// 调用webpack并把配置传递过去
var compiler = webpack(webpackConfig);
// 使用 webpack-dev-middleware 中间件
var devMiddleware = require(‘webpack-dev-middleware’)(compiler, {
publicPath: ‘/‘,
stats: { colors: true, chunks: false }
});
app.use(devMiddleware);
app.use(require(“webpack-hot-middleware”)(compiler));

}
module.exports = app;

重新启动服务查看效果

五、添加路由实现单页应用

1.按照下图添加文件夹和文件

Paste_Image.png

说明:

components文件夹中放公用组件

router放置路由相关配置的js

views下放置单页的vue,按照模块放置

现在模拟一个场景:

有两个页面首页和用户页

1.修改main.js

import Vue from “vue”;
import router from ‘./router/index’;//引入路由配置
import App from “./app”;
import VueRouter from “vue-router”;

Vue.config.debug = true;//开启错误提示

Vue.use(VueRouter);

const app = new Vue({
el:’#app’,
router:router,//添加路由配置
render: h => h(App)
});

2.修改app.vue

添加(路由更新的地方)

注意中的代码必须有一个包裹元素

3.在/src/router/index.js中添加:

import VueRouter from “vue-router”;
import Index from “../views/Index/index”;
import User from “../views/User/user”;
const routes = [
{
path:’/‘, component:Index
},
{
path:’/user’, component:User
}];
const router = new VueRouter({ mode: ‘history’, routes});
module.exports = router;

4.在index.vue和user.vue中分别加上

5.运行npm install –save connect-history-api-fallback,然后在app.js中加入

var history = require(‘connect-history-api-fallback’);

app.use(history());//放在app.use(devMiddleware);之前才有效(放在 if(app.get(‘env’) == ‘development’){ 之前)

单页请求,需要加上connect-history-api-fallback中间件否则会报404

注意:一定要放在app.use(devMiddleware);之前才有效

参考:https://github.com/bripkens/connect-history-api-fallback

重启服务,就可以访问http://localhost:3000看到如下

Paste_Image.png

访问http://localhost:3000/user 效果如下

Paste_Image.png

完成以上步骤就可以开发用vue开发一个简单的单页应用了

五、生成环境打包

1.运行 npm instal shelljs ora –save-dev

2.在build文件下创建一个webpack.prod.conf.js.内容如下:

var path = require(‘path’);
var webpack = require(‘webpack’);
var merge = require(‘webpack-merge’);
// 引入基本配置
var webpackConf = require(‘./webpack.base.conf’);
var prodWebpackConf = merge(webpackConf,{
output:{ publicPath:’/‘, filename: ‘static/js/[name].[hash].js’ },
plugins:[
new webpack.optimize.UglifyJsPlugin({
compress: { warnings: false }
})
]});
module.exports = prodWebpackConf;

3.在build文件下创建一个build.js文件,内容如下:

// https://github.com/shelljs/shelljs
require(‘shelljs/global’);
var path = require(‘path’);
var ora = require(‘ora’);
var webpack = require(‘webpack’);
var webpackConf = require(‘./webpack.prod.conf’);
console.log( ‘ Tip:\n’ + ‘ Built files are meant to be served over an HTTP server.\n’ + ‘ Opening index.html over file:// won't work.\n’);
var spinner = ora(‘building for production…’);
spinner.start();
var assetsPath = path.join(‘/‘, ‘static’);
rm(‘-rf’, assetsPath);
mkdir(‘-p’, assetsPath);
cp(‘-R’, ‘static/‘, assetsPath);
webpack(webpackConf, function (err, stats) {
spinner.stop();
if (err) throw err
process.stdout.write(stats.toString({
colors: true,
modules: false,
children: false,
chunks: false,
chunkModules: false
}) + ‘\n’)
});

4.在package.json的script中添加 “build”: “node build/build.js”

5.运行npm run build 之后会生成一下文件

Paste_Image.png

6.修改app.js,在if(app.get(‘env’) == ‘development’){……}条件后添加

else{

app.use(express.static(‘output’));

}

7.在package.json的script中添加 “prod”:”cross-env NODE_ENV=production node bin/www”

8.运行npm run prod 就可以查看成产环境了

9.一般生成环境用pm2来起服务,于是在根目录下创建pm2.json 内容如下:

{ “apps”: [ { “script”: “bin/www” } ]}

connect-history-api-fallback中间件注册一定要在app.use(express.static(path.join(__dirname, ‘output’)));之前

10.在package.json的script中添加 “pm2_start”:”cross-env NODE_ENV=production pm2 start pm2.json”

运行 npm run pm2_start就可用pm2启动服务 (运行前需要安装过全局的pm2 , npm install -g pm2)

完成以上步骤就可以基本完成一个简单的vue单页应用了

注意

1.connect-history-api-fallback中间件注册一定要在webpack-dev-middleware中间件注册之前

2.connect-history-api-fallback中间件注册一定要在app.use(express.static(path.join(__dirname, ‘output’)));之前

参考链接:

1.vue2官网:http://cn.vuejs.org/v2/guide/

2.vue-loader文档:https://vue-loader.vuejs.org/en/

3.vue-cli创建项目介绍:https://vuejs-templates.github.io/webpack/

4.Vue作者尤雨溪:Vue 2.0,渐进式前端解决方案

CommonJS

服务器端的 Node.js 遵循 CommonJS规范,该规范的核心思想是允许模块通过 require 方法来同步加载所要依赖的其他模块,然后通过 exports 或 module.exports 来导出需要暴露的接口。

require(“module”);
require(“../file.js”);
exports.doStuff = function() {};
module.exports = someValue;

优点:

  • 服务器端模块便于重用

  • NPM 中已经有将近20万个可以使用模块包

  • 简单并容易使用

缺点:

  • 同步的模块加载方式不适合在浏览器环境中,同步意味着阻塞加载,浏览器资源是异步加载的

  • 不能非阻塞的并行加载多个模块

实现:

  • 服务器端的 Node.js

  • Browserify,浏览器端的 CommonJS 实现,可以使用 NPM 的模块,但是编译打包后的文件体积可能很大

  • modules-webmake,类似Browserify,还不如 Browserify 灵活

  • wreq,Browserify 的前身

AMD

Asynchronous Module Definition 规范其实只有一个主要接口 define(id?, dependencies?, factory),它要在声明模块的时候指定所有的依赖 dependencies,并且还要当做形参传到 factory 中,对于依赖的模块提前执行,依赖前置。

define(“module”, [“dep1”, “dep2”], function(d1, d2) {
return someExportedValue;
});
require([“module”, “../file”], function(module, file) { /* … */ });

优点:

  • 适合在浏览器环境中异步加载模块

  • 可以并行加载多个模块

缺点:

  • 提高了开发成本,代码的阅读和书写比较困难,模块定义方式的语义不顺畅

  • 不符合通用的模块化思维方式,是一种妥协的实现

实现:

  • RequireJS

  • curl

CMD

Common Module Definition 规范和 AMD 很相似,尽量保持简单,并与 CommonJS 和 Node.js 的 Modules 规范保持了很大的兼容性。

define(function(require, exports, module) {
var $ = require(‘jquery’);
var Spinning = require(‘./spinning’);
exports.doSomething = …
module.exports = …
})

优点:

  • 依赖就近,延迟执行

  • 可以很容易在 Node.js 中运行

缺点:

  • 依赖 SPM 打包,模块的加载逻辑偏重

实现:

  • Sea.js

  • coolie

1
2
3
4
5
6
7
8
9
10
11
12
13
data = {};
_data = {key: 'value'};
Object.defineProperty(data, 'key', {
get: function(){
return _data['key'];
},
set: function(value){
_data['key'] = value;
console.log('set prop key to ' + value);
},
enumerable: true,
configurable: false
});
  • configurable
    true当且仅当此属性描述符的类型可能被改变并且该属性可以从相应的对象被删除时。
    默认为false。

  • enumerable
    true如果且仅当此属性在对相应对象的属性枚举期间显示。
    默认为false。

数据描述符还具有以下可选键:

  • value
    与属性关联的值。可以是任何有效的JavaScript值(数字,对象,函数等)。
    默认为undefined。

  • writable
    true当且仅当与属性相关联的值可以与改变赋值运算。
    默认为false。

访问器描述符还具有以下可选键:

  • get
    其用作属性的吸气剂的函数,或者undefined如果没有吸气。函数返回将用作属性的值。
    默认为undefined。

  • set
    它作为对属性的设置的函数,或者undefined如果没有二传手。该函数将仅接收作为参数的新值分配给属性。
    默认为undefined。

文件

node_modules配置文件

package.json

node服务脚本文件

server.js

使用方法

1、下载上面两个文件,放到webapp目录下

2、在webapp目录启动gitbash或其它支持npm的命令行工具

3、执行npm install安装依赖包

4、执行node server或npm run test启动服务

5、在localhost:3000访问静态服务

0%