13、gulp、webpack、三大框架之登錄|權限|路由嵌套|狀態管理|請求響應攔截、angular1項目下index.html的注入與執行、安裝服務器系統、操作服務器系統、Linux|ubuntu|VMware、electron、服務端渲染、__dirname|join|resolve、npm|cnpm|yarn|tyarn|bootstrap


一、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/**/*.js3)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.892)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 Downloads2)安裝搜狗輸入法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。20165 月 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.啟動(電腦)
 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM