一、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.啟動(電腦)