vue05-es6模塊化和webpack


五、es6模塊化

阮一峰的ES6---Module的加載實現

把功能進行划分,將同一類型的代碼整合在一起,所以模塊的功能相對復雜,但都同屬於一個業務

為什么有模塊化

  • js是按順序加載的,所以一般相互依的js是具有強制性的
  • 多個js文件定義的引用會污染全局變量,多人協作開發可能會有沖突
  • 可以用閉包

閉包解決多人協作開發

  • 只需要寫好自己的模塊化的命名,就可以很好的避免沖突了,相當於把所有的容錯點都聚焦在一個點上,犯錯的機會就少了,
  • 但是代碼的復用性還是很差
// ;是為了防止其他的導入js相互影響
;var xm01 = (function xiaoming01() {
  return {
    aa:"asdas",
    flag: true
  };
}())


//js文件2
;(function () {
  if (xm01.flag) {
    alert("xm01.flag:" + xm01.flag);
  }
}());

組件化類似模塊化的更細粒度,組件充當了基本類庫一樣的東西目的是復用拓展性,模塊主要是以功能區分類別划分盡量隔離其他業務

模塊化練習

  • xiaoming01.js

    // es6的導出,02中導入
    export let exa = "222";
    let exa1 = "333";
    let exb = "333";
    
    export {exb, exa1};
    export function fun(){
      console.log("asasddsds");
    }
    
    
    //export default :import的時候可以自定義命名,一個js中只能有一個default
    let aaa="export default";
    export default aaa;
    
  • xiaoming02.js

    // 導入 ,這里需要寫上.js
    import {exa, exa1, exb} from "./xiaoming01.js";
    // 01
    console.log(exa1, exb);
    
    //導入default可以自定義命名
    import asd from "./xiaoming01.js";
    
    console.log('export:',asd);
    
    //導入全部的導出,並且重命名
    import * as all from "./xiaoming01.js";
    
    console.log(all);
    console.log(all.default)
    
    
    
  • 01-es6.html

    • script需要指定type=module
    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <title>Title</title>
      <script src="./xiaoming01.js" type="module"></script>
      <script src="./xiaoming02.js" type="module"></script>
    </head>
    <body>
    沒有使用導入導出的話:
    Uncaught ReferenceError: flag is not defined
    at xiaoming02.js:3
        以前是可以執行的先在不知道怎么執行不了了
    </body>
    </html>
    

六、webpack

webpack起步

*webpack* 是一個現代 JavaScript 應用程序的*靜態模塊打包器(module bundler)*。當 webpack 處理應用程序時,它會遞歸地構建一個*依賴關系圖(dependency graph)*,其中包含應用程序需要的每個模塊,然后將所有這些模塊打包成一個或多個 *bundle*(捆,束),它做的事情是,分析你的項目結構,找到JavaScript模塊以及其它的一些瀏覽器不能直接運行的拓展語言(Scss,TypeScript等),並將其打包為合適的格式以供瀏覽器使用。
  • 入口js

    //commonjs規范
    const {add} = require('./mathUtil.js');
    
    console.log(add(1,3));
    
    //es6規范
    import {result} from "./es6.js";
    
    console.log(result);
    
  • es6規范

const result = 45456;
export {result};
  • common規范
function add(a, b) {
  return a + b;
}

module.exports = {add};

webpack配置

  • 導出的時候es6和commonjs不能在一個模塊中混用
  • 配置webpack.config.js:要使用commonjs規范
//node的包里面的path模塊,用來拼接絕對路徑
const path = require('path');

//這里要用commonjs導出,不能用es6
module.exports = {
    //打包轉換的調用入口和main方法類似
  entry: './src/main.js',
  ouput: {
    //必須使用絕對路徑,path.resolve(__dirname,'dist')返回絕對路徑
    path: path.resolve(__dirname,'dist'),
    filename: 'bundle.js'
  }
};
  • package.json配置:json不能有注釋
{
  "name": "meetpackage",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    //npm run build 會在這個配置文件中找webpack命令,這個使用的是本地的命令,
    //不是全局的webpack,本地是針對於你的這個開發項目
    "build":"webpack"
  },
  "author": "",
  //開發的依賴
   "devDependencies": {
    "webpack": "^3.6.0"
  },
  //開源才需要這個,json中不能注釋
  "license": "ISC"
}

  • 本地安裝:開發時依賴 npm install webpack@3.6.0 --save-dev
  • 終端terminal里敲的命令都是全局的
為什么使用--save-dev而不是--save?

--save 會把依賴包名稱添加到 package.json 文件 dependencies 下;

--save-dev 則添加到 package.json 文件 devDependencies 鍵下;

webpack-loader

  • 官網可以找到對應的loader安裝
    • 例:npm install style-loader[@version] --save -dev[表示開發環境用]
    • npm install babel-loader@7 babel-core babel-preset-es2015 --save-dev es6轉es5
//node的包里面的path模塊,用來拼接絕對路徑
const path = require('path');

//這里要用commonjs導出,不能用es6
module.exports = {
  entry: './src/main.js',
  output: {
    //必須使用絕對路徑
    path: path.resolve(__dirname,'dist'),
    filename: 'bundle.js',
    //為所有的url相關的添加路徑
    publicPath:'dist/'
  },
  module:{
    rules: [
      {
        test: /\.css$/,
        // style-loader將模塊的導出作為樣式添加到 DOM 中
        // loader解析 CSS 文件后,使用 import 加載,並且返回 CSS 代碼
        // 從右到左的順序加載
        use: [ 'style-loader', 'css-loader' ]
      },
      // {
      //   test: /\.(png|jpg|gif)$/,
      //   use: [
      //     {
      //       loader: 'url-loader',
      //       options: {
      //         //限制圖片大小,大於limit會找file-loader
      //         limit: 9999
      //       }
      //     }
      //   ]
      // },
      // 在使用webpack進行打包時,對圖片路徑的處理方法常用的有兩種,一種是file-loader,
      // 一種是url-loader,當我們使用其中一種是,請把另一種刪掉,不然會出現圖片無法正常顯示的問題
      {
        test: /\.(png|jpg|gif)$/,
        use: [
          {
            loader: 'file-loader',
            options: {
              //name是文件名,hash取8位,ext是拓展名
              name:'img/[name].[hash:8].[ext]'
            }
          }
        ]
      },
      {
        test: /\.js$/,
        exclude: /(node_modules|bower_components)/,
        use: {
          loader: 'babel-loader',
          options: {
            presets: ['es2015']
          }
        }
      }
    ]
  }
};

webpack-vue

  1. npm install vue -save

  2. 不寫路徑默認從node_modules引入 import Vue from 'vue'

  3. runtime-only:是運行的時候代碼不能包含任意一個template標簽

  4. runtime-compiler:代碼中可以有template標簽

    1. 解決3.4碰到的問題
     module:{
    
      resolve:{
        alias:{
          // vue$正則,表示導入的時候會檢測vue指向的文件夾,如果這里不指定,會去找默認的runtime-only
          'vue$':'vue/dist/vue.esm.js'
        }
      }
    
//使用vue
import Vue from 'vue';


const App = {
    template: `
    <h2>{{msg}}</h2>
    `,
    data() {
        return {
            msg: 'hello world'

        };
    }
};

new Vue({
    el: '#app',
    // template和el關系是,這里的template會替換el的標簽
    template: `<App/>`,
    components: {
        App
    }
});
將組件的代碼提出去
  • 新建一個.vue文件
<template>
  <h2>{{msg}}</h2>
  <span class="title">{{tit}}</span>
</template>

<script>
  export default {
    name: "App",
    data() {
      return {
        msg: 'hello world',
        tit:'title'
      };
    }
  }
</script>

<style scoped>
.title{
  color: red;
}
</style>
  • npm install vue-loader vue-template-compiler --save -dev
    • 會出現版本過高的問題 安裝一個低版本的
    • 編輯package.json中的版本號,會根據你的大版本找一個合適的,必須重新npm install

webpack-plugin

  • 安裝打包靜態文件:npm install --save-dev html-webpack-plugin
  • 壓縮js文件替換變量為更簡單的:npm install uglifyjs-webpack-plugin@1.1.1 --save -dev 指定的vueCli 2
webpack-dev-server
  • 全局安裝:可以不用

    npm install webpack-dev-server -g 
    
  • 開發環境:

    npm install webpack-dev-server -save -dev
    
  • 配置參數:

    --content-base //設定webpack-dev-server的director根目錄。如果不進行設定的話,默認是在當前目錄下。
    --quiet: //控制台中不輸出打包的信息,開發中一般設置為false,進行 打印,這樣查看錯誤比較方面
    --no-info: // 不顯示任何信息
    --colors: //對信息進行顏色輸出
    --no-colors: //對信息不進行顏色輸出
    --compress:  //開啟gzip壓縮
    --host <hostname/ip>: //設置ip
    --port <number>: //設置端口號,默認是:8080
    --inline: //webpack-dev-server會在你的webpack.config.js的入口配置文件中再添加一個入口,
    --hot: //開發熱替換
    --open: //啟動命令,自動打開瀏覽器
    --history-api-fallback: //查看歷史url
    
  • 兩種方式:

    1. 直接scripts中使用:"dev": "webpack-dev-server --contentBase src --port 80 --hot --colors"
    2. 配置文件:
      plugins: [
        new webpack.BannerPlugin('最終版權是小明'),
        //打包靜態資源,並且指定模板
        new htmlWebpackPlugin({
          template:`index.html`
        }),
        //壓縮js
        new UglifyJsWebpackPlugin(),
        //熱加載,不會全部加載,只加載改動的地方,配置了hot就需要配置,直接在命令中使用--hot就不需要配置這個插件
        // new webpack.HotModuleReplacementPlugin()
      ],
      // devServer: {
      //   contentBase: 'src',
      //   port: 80,
      //   hot:true
      // },
    
  • 報錯可能是版本問題

webpack.config.js配置文件

//node的包里面的path模塊,用來拼接絕對路徑
const path = require('path');
const webpack = require('webpack');
const htmlWebpackPlugin = require('html-webpack-plugin');
const UglifyJsWebpackPlugin = require('uglifyjs-webpack-plugin');

//這里要用commonjs導出,不能用es6
module.exports = {
  entry: './src/main.js',
  output: {
    //必須使用絕對路徑
    path: path.resolve(__dirname, 'dist'),
    filename: 'bundle.js',
    //為所有的url相關的添加路徑
    // publicPath: 'dist/'
  },
  module: {
    rules: [
      {
        test: /\.css$/,
        // style-loader將模塊的導出作為樣式添加到 DOM 中
        // loader解析 CSS 文件后,使用 import 加載,並且返回 CSS 代碼
        // 從右到左的順序加載
        use: ['style-loader', 'css-loader']
      },
      // {
      //   test: /\.(png|jpg|gif)$/,
      //   use: [
      //     {
      //       loader: 'url-loader',
      //       options: {
      //         //限制圖片大小,大於limit會找file-loader
      //         limit: 9999
      //       }
      //     }
      //   ]
      // },
      // 在使用webpack進行打包時,對圖片路徑的處理方法常用的有兩種,一種是file-loader,
      // 一種是url-loader,當我們使用其中一種是,請把另一種刪掉,不然會出現圖片無法正常顯示的問題
      {
        test: /\.(png|jpg|gif)$/,
        use: [
          {
            loader: 'file-loader',
            options: {
            //name是文件名,hash取8位,ext是拓展名
              name: 'img/[name].[hash:8].[ext]'
            }
          }
        ]
      },
      {
        test: /\.js$/,
        exclude: /(node_modules|bower_components)/,
        use: {
          loader: 'babel-loader',
          options: {
            presets: ['es2015']
          }
        }
      },
      {
        test: /\.vue$/,
        use: {
          loader: 'vue-loader'
        }
      }
    ]
  },
  resolve: {
    // 這寫拓展名可以省略
    extensions: ['.css', '.js', '.vue'],
    alias: {
      // vue$正則,表示導入的時候會檢測vue指向的文件夾,如果這里不指定,會去找默認的runtime-only
      'vue$': 'vue/dist/vue.esm.js'
    }
  },
  plugins: [
    new webpack.BannerPlugin('最終版權是小明'),
    //打包靜態資源,並且指定模板
    new htmlWebpackPlugin({
      template:`index.html`
    }),
    //壓縮js
    new UglifyJsWebpackPlugin(),
    //熱加載,不會全部加載,只加載改動的地方,配置了hot就需要配置,直接在命令中使用--hot就不需要配置這個插件
    // new webpack.HotModuleReplacementPlugin()
  ],
  // devServer: {
  //   contentBase: 'src',
  //   port: 80,
  //   hot:true
  // },
};

抽取分離配置文件

  • 創建三個配置文件:
    1. base.config.js : 存放公共的配置
    //node的包里面的path模塊,用來拼接絕對路徑
    const path = require('path');
    const webpack = require('webpack');
    const htmlWebpackPlugin = require('html-webpack-plugin');
    
    //這里要用commonjs導出,不能用es6
    module.exports = {
        entry: './src/main.js',
        output: {
            //必須使用絕對路徑
            path: path.resolve(__dirname, '../dist'),
            filename: 'bundle.js',
        },
        module: {
            rules: [
                {
                    test: /\.css$/,
                    // style-loader將模塊的導出作為樣式添加到 DOM 中
                    // loader解析 CSS 文件后,使用 import 加載,並且返回 CSS 代碼
                    // 從右到左的順序加載
                    use: ['style-loader', 'css-loader']
                },
                {
                    test: /\.(png|jpg|gif)$/,
                    use: [
                        {
                            loader: 'file-loader',
                            options: {
                                //name是文件名,hash取8位,ext是拓展名
                                name: 'img/[name].[hash:8].[ext]'
                            }
                        }
                    ]
                },
                {
                    test: /\.js$/,
                    exclude: /(node_modules|bower_components)/,
                    use: {
                        loader: 'babel-loader',
                        options: {
                            presets: ['es2015']
                        }
                    }
                },
                {
                    test: /\.vue$/,
                    use: {
                        loader: 'vue-loader'
                    }
                }
            ]
        },
        resolve: {
            // 這寫拓展名可以省略
            extensions: ['.css', '.js', '.vue'],
            alias: {
                // vue$正則,表示導入的時候會檢測vue指向的文件夾,如果這里不指定,會去找默認的runtime-only
                'vue$': 'vue/dist/vue.esm.js'
            }
        },
        plugins: [
            new webpack.BannerPlugin('最終版權是小明'),
            //打包靜態資源,並且指定模板
            new htmlWebpackPlugin({
                template: `index.html`
            })
        ],
    };
    
    1. dev.config.js : 存放開發時配置

      const WebpackMerge = require('webpack-merge');
      const baseConfig = require('./base.config');
      
      module.exports = WebpackMerge(baseConfig, {
          devServer: {
              contentBase: 'src',
              port: 80,
              inline: true
          }
      });
      
    2. prod.config.js : 存放生產時配置

      const UglifyJsWebpackPlugin = require('uglifyjs-webpack-plugin');
      const WebpackMerge = require('webpack-merge');
      const baseConfig = require('./base.config');
      
      module.exports = WebpackMerge(baseConfig, {
          plugins: [
              //壓縮js
              new UglifyJsWebpackPlugin()
          ]
      });
      
  • 修改scripts
    • 可刪除默認的webpack.config.js
    "scripts": {
        "test": "echo \"Error: no test specified\" && exit 1",
        "dev": "webpack-dev-server --config ./build/dev.config.js",
        "build": "webpack --config ./build/prod.config.js"
      },
    

打包

  • 使用webpack,也可以不用配置文件自己在命令后指定參數,以下是使用配置文件

  • 使用npm,會找到package.json找到對應的script里的命令執行,實際上還是調用了webpack命令


免責聲明!

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



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