一、gulp 1、gulp的API (1)gulp.src(globs[, options])导入文件的路径 (A)globs参数匹配文件路径(路径包括文件名,分为具体路径和通配符路径)。当有多个路径时,该参数为一个数组。 (B)options为可选参数。通常情况下我们不需要用到。 (C)* 匹配文件路径中的0个或多个字符,但不会匹配路径分隔符,除非路径分隔符出现在末尾 (D)** 匹配路径中的0个或多个目录及其子目录,需要单独出现,即它左右不能有其他东西了。如果出现在末尾,也能匹配文件。 (D)gulp.src(['js/*.js','css/*.css','*.html']) (E)使用数组的方式还有一个好处就是可以很方便的使用排除模式,在数组中的单个匹配模式前加上!即是排除模式,它会在匹配的结果中排除这个匹配,要注意一点的是不能在数组中的第一个元素中使用排除模式 (F)gulp.src([*.js,'!b*.js']) //匹配所有js文件,但排除掉以b开头的js文件 (G)gulp.src(['!b*.js',*.js]) //不会排除任何文件,因为排除模式不能出现在数组的第一个元素中 (2)gulp.dest(path[,options])导出文件的目录 (A)path为写入文件的路径 (B)options为一个可选的参数对象,通常我们不需要用到 (C)gulp.dest()传入的路径参数,只能用来指定要生成的文件的目录,生成的文件名是由导入到它的文件流决定的。 (D)gulp.dest(path)生成的文件路径是我们传入的path参数后面再加上gulp.src()中有通配符开始出现的那部分路径。例如: (D)gulp.src('script/**/*.js') .pipe(gulp.dest('dist')); //最后生成的文件路径为 dist/**/*.js (3)gulp.task(name[, deps], fn)用来定义任务 (A)name 为任务名 (B)deps 是当前定义的任务需要依赖的其他任务,为一个数组。当前定义的任务会在所有依赖的任务执行完毕后才开始执行。 (C)fn 为任务函数,我们把任务要执行的代码都写在里面。 (D)gulp.task('mytask', ['array', 'of', 'task', 'names'], function() { //定义一个有依赖的任务 // Do something}); (D)gulp中执行多个任务,可以通过任务依赖来实现。例如我想要执行one,two,three这三个任务,那我们就可以定义一个空的任务,然后把那三个任务当做这个空的任务的依赖就行了: //只要执行default任务,就相当于把one,two,three这三个任务执行了 (E)gulp.task('default',['one','two','three']); (F)如果任务相互之间没有依赖,任务会按你书写的顺序来执行,如果有依赖的话则会先执行依赖的任务。 (G)但是如果某个任务所依赖的任务是异步的,就要注意了,gulp并不会等待那个所依赖的异步任务完成,而是会接着执行后续的任务。 (4)gulp.watch(globs[, opts], tasks)或gulp.watch(glob[, opts, cb])用来监视文件的变化,当文件发生变化后,我们可以利用它来执行相应的任务 (A)globs参数匹配文件路径(路径包括文件名,分为具体路径和通配符路径)。当有多个路径时,该参数为一个数组。 (B)opts 为一个可选的配置对象,通常不需要用到 (C)tasks 为文件变化后要执行的任务,为一个数组 (D)cb参数为一个函数。每当监视的文件发生变化时,就会调用这个函数,并且会给它传入一个对象,该对象包含了文件变化的一些信息,type属性为变化的类型,可以是added,changed,deleted;path属性为发生变化的文件的路径 (E)gulp.watch('js/**/*.js', function(event){ console.log(event.type); //变化类型 added为新增,deleted为删除,changed为改变 console.log(event.path); //变化的文件的路径 }); 2、gulp介绍 (1)gulp自动化工具的作用: (A)打包,供生产环境使用。 (B)监听,供开发环境使用。 (2)gulp自动化工具的数据来源: (A)请求静态资源时,通过配置指向本机; (B)请求动态数据时,通过配置指向服务器。 (C)生产环境下,所有的数据都按照代码里面的url获取 3、在gulp下,建立karma任务 来源:https://www.cnblogs.com/2050/p/4198792.html var karma = require('karma').server; gulp.task('test', function(done) { karma.start({ configFile: __dirname + '/tests/my.conf.js', singleRun: true }, function() { done(); }); }); 4、gulpfile.js var fs = require('fs'); var url = require('url'); var gulp = require('gulp'); var Gaze = require('gaze').Gaze; var browserSync = require('browser-sync').create(); var reload = browserSync.reload; var proxy = require('proxy-middleware'); var getGulpPlugin = require('gulp-load-plugins')(); var runSequence = require('run-sequence'); 5、gulp开发流程 gulp.task('default', function () { testServe('cy', 'cy'); }); function testServe(moduleDirName, configDirname) { //(1)向index.html里注入js(含被压缩成js的html)、css injectAndReload(moduleDirName, configDirname); //(2)监听各路径下文件的增减和文件内容的改变 gaze && gaze.close(); browserSync && browserSync.exit(); gaze = new Gaze('src/**/*'); gaze.on('all', function () { injectAndReload(moduleDirName, configDirname); }); //(3)代理请求并重新加载index.html var myProxy = [ '/app', '/global', '/logio', ].map(function (value) { var a = url.parse('http://192.168.80.152:7300'+value); a.route = value; return proxy(a); }); browserSync.init({ port: 8900, notify: false, open: false, server: { baseDir: ['src'],//开发过程中,需要的所有文件都应该放在src文件夹下,尤其是某状态的html文件 directory: false, index: 'index.html', middleware: myProxy, routes: { '/audit-html/static/img': 'src/img',//服务器存放文件的路径:本地开发时存放文件的路径 '/config/project/static/img': 'src/img' } } }, function () { reload(); } ); } function injectAndReload(moduleDirName, configDirname) { var jsArray = getJsCssHtml(configDirname).js; var cssArray = getJsCssHtml(configDirname).css; var htmlArray = getJsCssHtml(configDirname).tpl; gulp.src(htmlArray) .pipe($.htmlmin({collapseWhitespace: true,removeComments: true,minifyCSS: true}))//将html连同它所在的文件夹一起抽出,并进行最基本的压缩(去空格、去注释) .pipe($.angularTemplatecache({module: 'app'}))//将各文件夹里的HTML按照路径合并到一个js文件里,并缓存到app模块里 .pipe(gulp.dest('template'));//导出js文件,下面与其它js拼接时,放在最后 var array = jsArray.concat(cssArray,['template/htmlJS.js']); gulp.src('src/tpl/index.html') .pipe($.inject(gulp.src(array), {relative: true}))//注入区域为<!-- inject:js --> <!-- endinject --> .pipe(gulp.dest('src/')) .on('end', reload); } 6、gulp打包流程 // 引进的类库只打包不压缩,自己写的文件既打包又压缩。 // 打包后的文件,在开发时都存放在文件夹dist下, // 在生产时都放在文件夹/audit-html/static/下; // 生产页面index.html在生产时,放在audit-html/template下 gulp.task('build', function () { gulp.src(['tmp', 'dist', 'rev']).pipe(clean());//清除文件夹内容,为本次打包腾地方 gulp.src(paths).pipe(gulp.dest('dist/img'));//导出图片,供页面加载时使用 gulp.src(['src/vendor/common-vendor/**']) .pipe(gulp.dest('dist/common'));//导出类库,供生产页面index.html的<link href="">和<script src=""></script>引用 gulp.src(['src/brows/*']).pipe(gulp.dest('dist/brows'));//导出浏览器,供交互时返回 gulp.src(['src/index.html'])//打包index.html里<!-- build:js scripts/all.min.js --><!-- endbuild -->之间的资源 .pipe($.useref())//将html进行合并。 .pipe($.if('*.js', $.ngAnnotate()))//解决angular中,依赖注入出错的问题 .pipe($.if('*.js', $.uglify()))//压缩js .pipe($.if('*.css', $.cleanCss()))//压缩css .pipe(gulp.dest('dist'));//导出文件为'dist/scripts/all.min.js',由注释标签里的内容决定 gulp.src(['./dist/style/all.min.css', './dist/script/all.min.js'])//添加hash后缀,避免新旧文件混淆 .pipe(rev())//添加hash后缀 .pipe(gulp.dest('./dist'))//导出文件为'dist/styles/all_34543.min.css'和'dist/styles/all_abcba.min.css',供生产页面index.html的<link href="">和<script src=""></script>引用 gulp.src(['dist/scripts/all.min.js','dist/styles/all.min.css','dist/index.html'])//删除临时文件,只留将上线的文件 .pipe(clean());//删除上面三个文件 }); 二、webpack chunk 代码块。 polyfill 兜底。在计算机中,变相实现不能直接实现的操作。 process 对象是一个 global 变量,提供有关当前 Node.js 进程的信息并对其进行控制。 npm与nodejs版本对应关系:https://nodejs.org/zh-cn/download/releases/ dll,动态链接库英文为DLL,是Dynamic Link Library的缩写。(Dynamic,[daɪˈnæmɪk],有活力的) 1、基本知识 (1)安装node环境,nodejs环境变量指的是node环境安装的地方 (2)安装webpack和webpack-cli包 (3)node是运行node文件的命令 (4)npm是node包管理器、npm run start/stop/test可以简写为npm start/stop/test (5)npm运行的包,必须写入到package.json里面才能运行 (6)npx运行的包,可以在任何地方运行,运行时,从本目录开始逐层向上直至全局(nodejs环境变量)寻找该包,找到就运行,没有找到就临时安装并直接运行,运行结束后删掉;如果想运行层级以外的版本,则加上版本号即可,如npx webpack-dev-server@3.10.3; (7)直接运行的包,如果本目录或全局安装了该包,可以直接运行,不需要npm和npx,如webpack、webpack-dev-server。 2、开发或生产环境 (1)webpack:是打包的命令,也是模块打包器。将entry输入的文件用module.rules编译打包后,根据mode取值不同而选择压不压缩最终的js,最后通过output把js显性输出到指定目录。 (2)webpack-cli:使webpack命令能(在命令行中)运行,cli即命令行接口(Command Line Interface)。 (3)webpack-dev-server:是开启本地node服务器的命令,也是一个小型的node服务器。将entry输入的文件用module.rules编译打包后,根据mode取值不同而选择压不压缩最终的js,最后通过output把js隐性输出到内存并自动打开浏览器,同时监听entry及其import引入的文件,一旦发生变化就自动编译、打包、隐性输出代码,手动刷新浏览器,可以看到最新效果。 (4)在(1)(3)编译的过程中,根据babel-loader的配置处理js的兼容,根据process.env.NODE_ENV取值不同,选择package.json里browserslist的不同配置项来处理css的兼容问题,根据插件配置决定最终的css压不压缩和输出目录,根据url-loader的配置决定最终的img输出目录和公共路径。 (5)以下webpack.config.js文件示例 const { resolve } = require('path'); const HtmlWebpackPlugin = require('html-webpack-plugin'); const MiniCssExtractPlugin = require('mini-css-extract-plugin'); const webpack = require('webpack'); process.env.NODE_ENV = "development";//打包时使用package.json里browserslist里development配置来处理js/css兼容,即兼容到各浏览器的哪个版本; module.exports = { entry: './src/js/index.js',//引入js,字符串和数组为单入口,对象为多入口;另外对象的value也可以是数组 output: { filename: 'js/built.js',//导出js文件,如果和entry路径的深度不一样,那么webpack会自动调整图片的引用路径 path: resolve(__dirname, 'build') }, publicPath: '/',// 给所有资源引入公共路径前缀'/',如'imgs/a.jpg'==>'/imgs/a.jpg' mode: 'development',//用webpack打包时不压缩,取'production'则压缩 module: { rules: [//loader配置 { test: /\.less$/,// 处理less资源 use: ['style-loader', 'css-loader', 'less-loader']//从右向左执行 //'style-loader'开发环境用。在下面的js文件里,隐式地为每个样式文件创建一个style标签并将该样式放入,再将每一个style标签插到head标签里;隐式地自动将output.filename引给JavaScript标签并插入到template里的body标签里。这样head标签里不会有style标签,但控制台里有。 //'css-loader',将css文件整合到js文件中 //'less-loader'将less文件转换为css文件 }, { test: /\.css$/, use: [//从下向上执行 MiniCssExtractPlugin.loader,//提取下面js里的css成单独文件。 'css-loader',//将css文件整合到js文件中 { loader: 'postcss-loader',//css兼容处理 /* 一、css兼容处理: 1、postcss-loader(提供postcss) 2、postcss-preset-env(帮postcss找到package.json中browserslist里面的配置,加载指定的css兼容性样式) 3、package.json中的相关配置 "browserslist": { "development": [//设置node环境变量:process.env.NODE_ENV = "development" "last 1 chrome version", "last 1 firefox version", "last 1 safari version" ], "production": [//默认是看生产环境 ">0.2%", "not dead", "not op_mini all" ] } */ options: { ident: 'postcss', plugins: () => [// postcss的插件 require('postcss-preset-env')() ] } } ] }, { test: /\.js$/, exclude: /node_modules/, use: [ { /* 开启多进程打包。 进程启动大概为600ms,进程通信也有开销。 只有工作消耗时间比较长,才需要多进程打包 */ loader: 'thread-loader', options: { workers: 2 // 进程2个 } }, { loader: 'babel-loader',//js兼容处理 /* 二、js兼容处理: 1、基本兼容处理如箭头函数,用(1)babel-loader(显性使用)(2)@babel/core(隐性支持)(3)@babel/preset-env(显性使用) 2、复杂兼容处理如promise,除了1以外,还需要用按需加载的(4)core-js(显性使用)或全部引入的(5)@babel/polyfill(显性使用) 3、【babel-loader@8 requires Babel 7.x (the package '@babel/core')】 */ options: { presets: [// 预设:指示babel做怎么样的兼容性处理 [ '@babel/preset-env', { useBuiltIns: 'usage',// 按需加载 corejs: {version: 3},// 指定core-js版本 targets: {// 指定兼容性做到哪个版本浏览器 chrome: '60', firefox: '60', ie: '9', safari: '10', edge: '17' } } ] ], cacheDirectory: true//开启babel缓存,第二次构建时,会读取之前的缓存 } } ] }, { test: /\.js$/, exclude: /node_modules/, include: resolve(__dirname, 'src'),// 只检查 src 下的js文件 enforce: 'pre',//2个js匹配,这个优先执行。也可以像处理css文件那样,把2个包放到1个use数组里。延后执行'post' loader: 'eslint-loader', /* 三、js语法检查: 1、eslint-loader(显性使用) eslint(隐性支持),eslint-config-airbnb-base(隐性支持) eslint-plugin-import(隐性支持) 2、package.json中的相关配置 "eslintConfig": { "extends": "airbnb-base" } 3、//eslint-disable-next-line,下一行所有eslint规则都失效 */ options: { fix: true// 自动修复eslint的错误 } }, { test: /\.(jpg|png|gif)$/,// 处理.css中的图片 loader: 'url-loader',//在.css中的图片,通过css-loader存储到js文件中,在js文件里改名后,可根据图片大小将图片转码为base64保存在js中或用common.js(默认用ES6,在配置中被esModule:false关闭)模块导出。js里存储了图片改前名和改后名的关联,后来再用到这张图片时会用到这个关联。 options: { limit: 8 * 1024, name: '[hash:10].[ext]', esModule: false,// 关闭es6模块化 outputPath: "img", publicPath: "/img", } }, { test: /\.html$/,// 处理html中的图片 loader: 'html-loader'//在.html文件img标签中的图片,用common.js模块处理,从而能被url-loader进行处理。 }, { exclude: /\.(html|js|css|less|jpg|png|gif)/,// 处理其他资源 loader: 'file-loader',//原封不动地输出文件 options: { name: '[hash:10].[ext]', outputPath: 'media', publicPath: "/media", }, } ] }, plugins: [ new MiniCssExtractPlugin({ filename: 'css/built.css'//导出css文件。默认配置为filename: './main.css' }), new OptimizeCssAssetsWebpackPlugin(),//对上面导出的css进行压缩 new HtmlWebpackPlugin({//将导出的js文件或css文件插入到html文件head-link里或body-script里 template: './src/index.html', minify: { collapseWhitespace: true,//去除index.html里面的空白 removeComments: true//去除index.html里面的注释 } }), new webpack.NamedModulesPlugin(), // 告知哪个文件被热替换(非必需) new webpack.HotModuleReplacementPlugin(), // 热替换插件 new WorkboxWebpackPlugin.GenerateSW({ /* 1. 帮助serviceworker快速启动 2. 删除旧的 serviceworker 生成一个 serviceworker 配置文件~ */ clientsClaim: true, skipWaiting: true }) ], devServer: {//开发环境必有 compress: true,// 启动gzip压缩 contentBase: resolve(__dirname, 'build'),// 告诉服务器内容的来源。仅在需要提供静态文件时才进行配置。 watchContentBase: true,// 监视 contentBase 目录下的所有文件,一旦文件变化就会 reload watchOptions: { ignored: /node_modules/// 忽略文件 }, port: 5000,// 端口号 host: 'localhost',// 域名 open: true,// 自动打开浏览器 hot: true,// 开启HMR功能,需要插件webpack.HotModuleReplacementPlugin配合 proxy: {// 服务器代理 --> 解决开发环境跨域问题 '/api': {// 一旦服务器5000接收到'/api/xxx'的请求 target: 'http://localhost:3000',//就会把请求转发到另外一个服务器3000 pathRewrite: {// 发送请求时,请求路径重写:将/api去掉 '^/api': '' } } }, clientLogLevel: 'none',// 不要显示启动服务器日志信息 quiet: true,// 除了一些基本启动信息以外,其他内容都不要显示 overlay: false,// 如果出错了,不要全屏提示~ }, devtool: "nosources-source-map",//正常情况下,此配置项缺失比加上更好 resolve: {// 解析模块的规则 alias: {// 配置解析模块路径别名: 优点简写路径 缺点路径没有提示 $css: resolve(__dirname, 'src/css') }, extensions: ['.js', '.json', '.jsx', '.css'],// 配置省略文件路径的后缀名 modules: [resolve(__dirname, '../../node_modules'), 'node_modules']// 告诉 webpack 解析模块是去找哪个目录 } optimization: { /* 1. 可以将node_modules中(除dll外)代码单独打包一个chunk最终输出 2. 自动分析多入口chunk中,有没有公共的文件。如果有会打包成单独一个chunk */ splitChunks: { chunks: 'all' } }, externals: {//用CDN时,需要此项配置;用dll时不能有此项配置。 jquery: "jquery", // 不打包第三方类库jquery vue: "vue", // 不打包第三方类库vue }, }; 3、工程化优化之HMR,热模块替换。 (1)当webpack-dev-server运行时,不使用HMR,一个模块发生改变,所有模块都重新打包,最后浏览器重新渲染;使用HMR,一个模块发生改变,只会重新打包这一个模块,最后浏览器重新(请求)渲染。 (2)不采用尚硅谷的热模块方案,因为里面讲的是原理,当监听到变化时,执行的是函数,而不是打包和刷新。另外,后来我在写配置文件时,开发环境和生产环境,都用MiniCssExtractPlugin.loader,不用'style-loader'。 (3)采用热模块的正常方案,A、new webpack.NamedModulesPlugin(),获取热模块的模块名;B、new webpack.HotModuleReplacementPlugin()打包热模块 (4)没有重新请求的渲染不会导致控制台以前的数据丢失。 4、工程化优化之使用缓存 (1)通常情况下,在本地打包前端所有文件,然后上传给远端服务器的最终目录,替换掉原来的前端文件。这个替换时间比较长,有可能影响正常的网站访问。 (2)一般情况下,将改动的某个前端文件上传给远端服务器的临时目录,当只有js/css文件发生改变时,只打包js/css文件到最终目录里,在最终目录里,用最新的js/css文件名替换掉index.html上原来的文件名,这个替换时间比较短,同时删掉原来的js/css文件。 (3)使用缓存时,文件命名规则{filename: "js/built.[contenthash:10].js"/"css/built.[contenthash:10].css"} 5、工程化优化之去除无用代码 (1)tree shaking,摇树优化 (2)前提:必须使用ES6模块化、开启production环境 (3)作用: 减少代码体积 (4)在package.json中配置 "sideEffects": false//所有代码都没有副作用(都可以进行tree shaking) "sideEffects": ["*.css","*.less"]//.css、.less不要优化,因为优化可能会把@babel/polyfill文件删掉 6、工程化优化之多入口 (1)有多个入口、有多个输出、index.html有多个注入 示例 entry: { index: './src/js/index.js', test: './src/js/test.js' }, (2)入口文件为单入口,但文件内部通过import动态导入语法,能将某个文件单独打包 (3)optimization:见上面配置项optimization { /* 1. 可以将node_modules中(除dll外--自悟)代码单独打包一个chunk最终输出 2. 自动分析多入口chunk中,有没有公共的文件。如果有会打包成单独一个chunk */ splitChunks: { chunks: 'all' } }, 7、工程化优化之PWA (1)渐进式网络应用,可离线访问,英文为“Progressive Web App”,见上面插件WorkboxWebpackPlugin。 (2)eslint不认识 window、navigator全局变量。解决:需要修改package.json中eslintConfig配置 "env": { "browser": true // 支持浏览器端全局变量 } (3)普通js文件 if ('serviceWorker' in navigator) { window.addEventListener('load', () => { navigator.serviceWorker .register('/service-worker.js') .then(() => { console.log('sw注册成功了~'); }) .catch(() => { console.log('sw注册失败了~'); }); }); } 8、工程化优化之dll (1)对第三方库单独打包,如:jquery、react、vue... (2)webpack.dll.js文件说明,用变量生成映射库 module.exports = { entry: { jquery: ["jquery"], vue: ["vue"], }, output: { filename: '[name].js', path: resolve(__dirname, 'dll'), library: '[name]_[hash]' // 打包库里向外文件的名称 }, plugins: [ new webpack.DllPlugin({ // 生成映射库 name: "[name]_[hash]", // 映射库里文件的名称 path: resolve(__dirname, "dll/manifest_[name].json"), // 输出多个文件时,文件名用变量 }), ], mode: 'development' }; (3)webpack.config.js文件说明,用列举使用映射库 const { resolve } = require('path'); const HtmlWebpackPlugin = require('html-webpack-plugin'); const webpack = require('webpack'); const AddAssetHtmlWebpackPlugin = require('add-asset-html-webpack-plugin'); module.exports = { entry: './src/index.js', output: { filename: 'built.js', path: resolve(__dirname, 'build') }, plugins: [ new HtmlWebpackPlugin({ template: './src/index.html' }), new webpack.DllReferencePlugin({// 使用映射库,把依赖的名称映射到built.js里模块的id上 manifest: resolve(__dirname, "dll/manifest_jquery.json"), }), new webpack.DllReferencePlugin({// 使用映射库,把依赖的名称映射到built.js里模块的id上 manifest: resolve(__dirname, "dll/manifest_vue.json"), }), new AddAssetHtmlWebpackPlugin([// 添加资源库,将资源打包出去,并在html中自动引入 { filepath: resolve(__dirname, "dll/jquery.js") },// 有多项时,用数组 { filepath: resolve(__dirname, "dll/vue.js") },// 只有一项时,直接用对象即可 ]), ], mode: 'development', }; 9、其它优化方法 (1)oneOf:[],只执行数组选项中的一个 (2)将多次使用的加载器放到一个数组里,供展开使用 (3)懒加载,当需要使用文件时才加载,比如点击某个按钮后才加载某个文件 (4)多进程:见上面配置thread-loader (5)不打包第三方类库:用externals排除第三方类库,用CND引入第三方库 三、三大框架之登录、权限、路由嵌套、状态管理、请求响应拦截 注:三大框架之登录和权限都走同一个逻辑 1、在angular1中, $rootScope.$on('$stateChangeStart', function (event, toState) { myServer.changeState(event, toState); //changeState检验登陆状态 //1、页面加载完毕,直接跳往登录页,2、登录成功后,跳往首页,3、根据登陆标志,向后台请求,获取权限信息,建立导航栏和选项卡。 }) (1)登录:页面加载完毕,根据$urlRouterProvider.otherwise('/login'),触发$stateChangeStart,不向后台发送请求。 (2)权限:登录成功后,跳转到首页,触发$stateChangeStart,向后台请求,获取权限信息,建立导航栏和选项卡。 (3)路由嵌套:<ui-view></ui-view> (4)状态管理:ui-router (5)请求响应拦截:$http 2、在vue中, (1)登录:渲染index.html时,跳转到path: '/',执行router.beforeEach,检查是否登录;沒登录则跳转到path: '/login'; (2)权限:登录成功后,设置标志,跳转到path: '/',再次执行router.beforeEach;向后台获取权限信息。 (3)路由嵌套:<router-view></router-view> (4)状态管理:vuex (5)请求响应拦截:service.interceptors const service = axios.create({ baseURL: process.env.BASE_API, timeout: 15000 }) service.interceptors.request.use(function(){}); service.interceptors.response.use(function(){}); 3、在react中, (1)登录:渲染index.html时,跳转到path: '/',执行dispatch action,检查是否登录;沒登录则跳转到path: '/login'; (2)权限:登录成功后,设置标志,跳转到path: '/',再次执行dispatch action;向后台获取权限信息。 (3)路由嵌套:{React.Children.map}或{props.children}或<header><Route path="/user" component={UsersMenu}/></header> (4)状态管理:react-redux (5)请求响应拦截:service.interceptors const service = axios.create({ baseURL: process.env.BASE_API, timeout: 15000 }) service.interceptors.request.use(function(){}); service.interceptors.response.use(function(){}); 4、导航、选项卡、页内按钮权限添加完毕后,进行无权限调试 (1)导航:if(条件)改为if(true) (2)选项卡:维持原样 (3)页内按钮:在检验是否登陆的逻辑里,定义account_data.all_roles.indexOf = function () { return true;}; (4)其它数据,比如登录名、角色等,随意 (5)以上操作均在stateChange函数里 (6)点击登录时,直接跳转正在调试的那个状态 四、angular项目下index.html的注入与执行, 1、生产页面 <!DOCTYPE html> <html lang="en" ng-controller="mainCtrl" ng-cloak> <head> <meta charset="UTF-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge" /> <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"/> <title ng-bind="r_g_company.info.title"></title> <link rel="shortcut icon" ng-href="{{r_g_company.info.favicon}}"/> <link rel="stylesheet" href="/audit-html/static/common/bootstrap.css"/> <link rel="stylesheet" href="/audit-html/static/common/editor.md/css/editormd.min.css"/> <link rel="stylesheet" href="/audit-html/static/common/animate.min.css"/> <link rel="stylesheet" href="/audit-html/static/styles/all_73567.min.css"/> </head> <body ondragstart="return false;"> <my-app></my-app> </body> <script src="/audit-html/static/common/jquery.js"></script> <script src="/audit-html/static/common/jquery-media.js"></script> <script src="/audit-html/static/common/echart.js"></script> <script src="/audit-html/static/common/webuploader.js"></script> <script src="../../static/scripts/all_yhg.min.js"></script>//回退一次就到根目录/audit-html了,再回退则忽略 </html> 2、index.html注入前页面 <!DOCTYPE html> <html lang="en" ng-controller="mainCtrl" ng-cloak> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"> <title ng-bind="r_g_company.info.title"></title> <link rel="shortcut icon" ng-href="{{r_g_company.info.favicon}}"> <link rel="stylesheet" href="/audit-html/static/common/bootstrap.css"> <link rel="stylesheet" href="/audit-html/static/common/sliderCaptcha/slidercaptcha.css"> <!-- build:css(src) styles/all.min.css --> 下面的css将被打包 <!-- inject:css --> css将注入到下面 <link rel="stylesheet" href="module/policy/cy/policy-flow-watch.css"> <link rel="stylesheet" href="module/policy/cy/policy-Anti-attack.css"> <!-- endinject --> css将注入到上面 <!-- endbuild --> 上面的css将被打包 </head> <body ondragstart="return false;"> <my-app></my-app> </body> <script src="/audit-html/static/common/jquery.js"></script> <script src="/audit-html/static/common/select.js"></script> <!-- build:js(src) scripts/all.min.js --> 下面的js将被打包 <!-- inject:js --> js将注入到下面 <script src="config/main.js"></script> <script src="module/role/cy/role-manage.js"></script> <!-- endinject --> js将注入到上面 <!-- inject:partials --> 特定js将注入到下面 <!-- angular templates will be automatically converted in js and inserted here --> <!-- endinject --> 特定js将注入到上面 <!-- endbuild --> 上面的js将被打包 </html> 3、index.html注入后页面 <!DOCTYPE html> <html lang="en" ng-controller="mainCtrl" ng-cloak> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"> <title ng-bind="r_g_company.info.title"></title> <link rel="shortcut icon" ng-href="{{r_g_company.info.favicon}}"> <link rel="stylesheet" href="/audit-html/static/common/bootstrap.css"> <link rel="stylesheet" href="/audit-html/static/common/sliderCaptcha/slidercaptcha.css"> <link rel="stylesheet" href="/audit-html/static/common/editor.md/css/editormd.min.css"> <link rel="stylesheet" href="/audit-html/static/common/animate.min.css"> <link rel="stylesheet" href="/audit-html/static/common/angular.treeview.css"> <link rel="stylesheet" href="/audit-html/static/common/nprogress/nprogress.css"> <!-- build:css(src) styles/all.min.css --> <!-- inject:css --> <link rel="stylesheet" href="module/common-css/animate.css"> <link rel="stylesheet" href="module/common-css/boot-reset.css"> <link rel="stylesheet" href="module/common-css/bower.css"> <!-- endinject --> <!-- endbuild --> </head> <body ondragstart="return false;"> <my-app></my-app> </body> <script src="/audit-html/static/common/jquery.js"></script> <script src="/audit-html/static/common/jquery-media.js"></script> <script src="/audit-html/static/common/sliderCaptcha/longbow.slidercaptcha.js"></script> <script src="/audit-html/static/common/angular.js"></script> <script src="/audit-html/static/common/angular-ui.js"></script> <!-- build:js(src) scripts/all.min.js --> <!-- inject:js --> <script src="config/main.js"></script> <script src="config/ctrl.js"></script> <script src="config/project/cy/logo.js"></script> <script src="config/project/cy/menu.js"></script> <script src="module/common-serve/data-g.js"></script> <script src="module/common-serve/date.js"></script> ...... <script src="module/role/cy/role-source.js"></script> <!-- endinject --> <!-- inject:partials --> <!-- angular templates will be automatically converted in js and inserted here --> <!-- endinject --> <!-- endbuild --> </html> 4、index.html中,js文件从上到下执行 (1)执行main.js, (A)注入依赖,当缓存中没有依赖key1、key2时,记依赖对象为{key1:null,key2:null,...}, (B)执行config和run (2)执行main.js文件下面的js文件,当key1、key2出现时,key1、key2修改依赖对象为{key1:value1,key2:value2,...}, (3)所有js文件执行完毕以后,如果key1或key2...没有出现,则会报错,不会执行config和run的参数,否则会执行。 (4)在模块初始化时,config的参数执行,对模块进行配置;只在angular项目启动时,run的参数执行,定义全局的数据或逻辑。 注:每个Angular“应用程序”ng-app都有一个 injector ,负责创建并查找依赖。 注:angular服务,必须先注入到config、run或controller里,然后才能使用。 (4)在index.js中定义组件myApp (function () { angular .module('common-dir', []) .directive('myApp', function () { console.log('myApp'); var dirAlert = '<dir-alert></dir-alert>'; var dirCommon = '<dir-common style="height:100%"></dir-common>'; var dirTip = '<dir-tip></dir-tip>'; var dirLoading = '<dir-load></dir-load>'; var template = ''.concat(dirCommon, dirAlert, dirTip, dirLoading); return { restrict: 'E', template: template, scope: false, link: function () { } }; }); })(); (5)在main.js中定义模块app (function () { angular .module('app', [ 'ui.router', 'angularTreeview', 'common-serve', 'module-login', 'module-role', ]) .config(function ($stateProvider, $urlRouterProvider, menu) { angular.forEach(menu, function (item) { angular.forEach(item.subs, function (it) { $stateProvider .state(it.state, it.cfg); }); }); $urlRouterProvider.otherwise('/login'); }) .run(function ($rootScope, account_m, app_init, account_data) { app_init .size_init() .key_init() .account_init(); $rootScope.$on('$stateChangeStart', function (event, toState) { NProgress.start(); account_m.start(event, toState); } ); $rootScope.$on('$stateChangeSuccess', function (event, toState) { account_data.state = toState.name; NProgress.done(); } ); }); })(); 五、安装服务器系统 1、通过FTP下载bin包至系统U盘 (1)bin包存放地址:192.168.80.89 (2)FTP用户名:cy-version (3)FTP密码:cy888888 (4)bin包存放路径:/versions/INA/INA-V2.0.4/ (5)下载bin包并存放至系统U盘 2、给服务器--插上--系统U盘 3、重启服务器(拔、插--电源,系统会自动安装成功,此过程耗时较长,点击COM3可以观看安装进程,出现OK和绿星,表示安装成功,此时服务器会自动断电) 4、给服务器--拔掉--系统U盘 5、重启服务器(拔、插--电源) 六、操作服务器系统 1、登陆服务器(用网线把我的电脑和服务器进行物理连接) (1)打开Xshell,点击COM3, (2)按enter键 (3)CyOS login: admin //xshell用户名 (4)Password:changyang123!@# //xshell密码 (5)CyOS# start //开启服务器 (6)Password:Cy@508# //服务器密码 2、给服务器配置IP (1)root@CyOS:/root# ifconfig mgmt0 192.168.10.156(给接口配置IP。它有65535个端口,ifconfig(配置))mgmt0(接口)) (2)按enter键,IP配置成功 3、启动服务器 (1)root@CyOS:/root# cd /usr/local/audit-web (2)root@CyOS:/usr/local/audit-web# python manage.py runserver 4、辅助步骤 (1)Ctrl+C(退出进程) (2)root@CyOS:/usr/local/audit-web# pkill -f python -9(杀死python进程,出现Address already in use时,需要用到这个命令) (3)root@CyOS:/usr/local/audit-web# pkill -f uwsgi -9(杀死名为uwsgi的进程) (4)root@CyOS:/usr/local/audit-web# iptables -P INPUT ACCEPT(关闭防火墙,P INPUT ACCEPT均大写) (5)root@CyOS:/usr/local/audit-web# ps aux|grep python(查看活进程,aux显示所有进程和进程状态,grep在这些里搜索) (6)root@CyOS:/root# ifconfig(显示或设置网络设备)///////////////////////// (7)root@CyOS:/root# cat /usr/local/etc/suricata/version.autogen(查看当前版本) (8)服务器重启:A、192.168.10.59不会丢失IP;B、192.168.10.156:5000会丢失ip;C、经过在审计项目进行如下操作设置-IP设置-设置本机IP-192.168.10.156-255.255.255.0-192.168.10.1后,ip不会丢失。 七、Linux,ubuntu和VMware 1、负载均衡 (1)CDN部署在网络提供商的机房,反向代理部署在网站的机房; (2)正向代理:客户端通过代理服务器向服务器发送请求,隐藏了真实的客户端; (3)反向代理:客户端访问代理服务器,代理服务器返回缓存内容,隐藏了真实的服务端; (4)Nginx:性能非常好的反向代理服务器,用来做负载均衡,可以在Linux系统中运行。 2、服务器硬件连接 (1)电源(服务器连到电源插座) (2)网线(服务器连接外网,可以通过ip访问) (3)主机(服务器通过COM连接自己的主机,可以直接访问) 3、Xshell新建 (1)新建串行接口COM3:文件-新建-名称(N):COM3,协议(P):SERIAL (2)新建远程接口NUMB:文件-新建-名称(N):192.168.10.156,协议(P):SSH,主机(H):192.168.10.156 4、“rm -rf”释义 (1)rm:remove;移除 (2)r:recursion;[rɪˈkɜːʃn];递归 (3)f:force;强制 5、Linux,ubuntu和VMware之间的关系 (1)Linux是一个操作系统; (2)Ubuntu是一个以桌面应用为主的Linux操作系统 (3)VMware是虚拟主机,在安装的过程中,导入ubuntu (4)在ubuntu里,应该用Linux命令来操作里面的文件 (5)安装步骤;点击VMware.exe文件直到结束-->点击桌面VMware图标-->点击“创建新的虚拟机”-->安装依赖(最后一步,耗时约40分钟) (6)4步完全卸载VMware。A、关闭VMware;B、应用卸载-->vmware-->修改-->下一步-->删除;C、C:\Program Files (x86)下删除VMware;D、C:\Users\用户名\Documents下删除Virtual Machines,内含ubuntu 6、在Ubuntu16.0.4里,基本操作 (1)获得超级用户权限:sudo su (2)重启虚拟机sudo reboot (3)安装包sudo apt-get install package (4)修复包sudo apt-get -f install (5)apt-get,是一条linux命令,用于自动从互联网的软件仓库中搜索、安装、升级、卸载软件或操作系统。 (6)apt是Linux下的一款安装包管理工具,apt = apt-get + apt-cache + apt-config 八、在Ubuntu16.0.4里,安装搜狗输入法和谷歌浏览器 1、安装简体中文输入法: (1)设置-系统设置-语言支持-安装-密码-确认-(安装fcitx,耗时约10分钟) (2)语言-安装/卸载语言-(勾选)中文简体-应用-密码-确认-(安装字体,耗时约10分钟) (3)区域格式-汉语中国-语言-(汉语中国)拉到第一位-(键盘输入法系统)fcitx-关闭 (4)删除包sudo apt-get remove fcitx-ui-qimpanel 附1:Fcitx是(Free Chinese Input Toy for X)的英文缩写,可为支持 XIM 的 X 应用程序提供输入服务。可以输入UTF-8编码中的汉字。 2、安装搜狗输入法 (1)下载搜狗输入法安装包http://pinyin.sogou.com/linux,进入下载目录cd Downloads (2)安装搜狗输入法sudo dpkg -i sogoupinyin_2.4.0.3469_amd64.deb (3)重启虚拟机sudo reboot (4)文字图标-配置当前输入法-(搜狗输入法个人版)调至第一个选项 3、安装过程中,可能遇到的问题及解决 问题1:updating cache ; waiting for apt-get to exit 解决1:sudo fuser -vki /var/lib/apt/lists/lock 问题2:由于找不到vcruntime140_1.dll,无法继续执行代码重新安装程序可能会解决此问题 解决2:下载文件vcruntime140_1.dll,复制到32/64位版本电脑的的C:\Windows\system64/32下 问题3:搜狗输入时出现乱码 解决3:killall fcitx 3、安装谷歌浏览器 (1)sudo wget http://www.linuxidc.com/files/repo/google-chrome.list -P /etc/apt/sources.list.d/ (2)wget -q -O - https://dl.google.com/linux/linux_signing_key.pub | sudo apt-key add - (3)sudo apt-get update (4)sudo apt-get install google-chrome-stable (5)/usr/bin/google-chrome-stable (6)在屏幕左侧的图标上,右键“锁定到启动器” 九、electron 1、electron是什么? (1)用Web技术构建跨平台的桌面应用,electron = Chromium + Node.js + Native API。2016 年 5 月 Electron 发布了 v1.0.0 版本 (2)Chromium,为 Electron 提供了强大的UI能力,可以不考虑兼容性的情况下,利用强大的Web生态来开发界面 (3)Node.js,让 Electron 有了底层的操作能力,比如文件的读写,甚至是集成C++等等操作,并可以使用大量开源的 npm 包来完成开发需求 (4)Native API,Native API 让 Electron 有了跨平台和桌面端的原生能力,比如说它有统一的原生界面,窗口、托盘这些。 2、什么时候使用Electron? (1)公司没有专门的桌面应用开发者,而需要前端兼顾来进行开发时,用Electron就是一个不错的选择。 (2)一个应用需要同时开发Web端和桌面端的时候,那使用Electron来进行开发就对了。 (3)开发一些效率工具,比如API类的工具。 十、服务端渲染 1、服务端渲染:服务器收到请求后,把数据拼接到html里,发送给浏览器渲染。 2、客户端渲染:服务器收到请求后,发送数据给浏览器,浏览器用js把数据拼接到html里,然后渲染。 3、怎样查看客户端首次渲染: (1)把http://localhost:8000粘贴到浏览器 (2)打开控制台console (3)刷新浏览器 十一、__dirname|join|resolve 1、__dirname和join var path = require("path"); console.log(__dirname); c:\Users\公司\Desktop\yuanma console.log(path.join(__dirname, "..", "src")); c:\Users\公司\Desktop\src console.log(path.join(__dirname, "../", "src")); c:\Users\公司\Desktop\src 2、__dirname和resolve var path = require("path"); console.log(__dirname); c:\Users\长扬科技\Desktop\yuanma console.log(path.resolve(__dirname, "..", "src")); c:\Users\长扬科技\Desktop\src console.log(path.resolve(__dirname, "../", "src")); c:\Users\长扬科技\Desktop\src 十二、npm|cnpm|yarn|tyarn|bootstrap 1、npm:最常用的包管理器。 2、cnpm:是npm的国内镜像。 3、yarn:是2016年重新设计发布的npm客户端,是并行下载的 4、tyarn:是yarn的国内镜像了。 5、npm install 安装命令示例,包名和后面的参数,位置可以互换。 (1)npm install 把package.json中的依赖配置,下载到本地项目的node_modules (2)npm install X 会把X包安装到项目的node_modules目录中,不会将模块依赖写入package.json中。 (3)npm install X -g 会把X包安装到全局的node_modules目录中,不会将模块依赖写入package.json中。 (4)npm install X --save 会把X包安装到项目的node_modules目录中,会在package.json的dependencies属性下添加X (5)npm install X --save-dev 会把X包安装到项目的node_modules目录中,会在package.json的devDependencies属性下添加X 6、npm其它命令 (1)npm help <command>可查看某条命令的详情 (2)npm update <package>可以把当前目录下node_modules子目录里边的对应模块更新至最新版本 7、bootstrap (1)n.[计]辅助程序 (2)vt.启动(电脑)