vue05-es6模块化和webpack

Posted 清风

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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命令

以上是关于vue05-es6模块化和webpack的主要内容,如果未能解决你的问题,请参考以下文章

webpack 打包和手动创建一个vue的项目

Vue报错:Uncaught TypeError: Cannot assign to read only property 'exports' of object 的解决方法(代码片段

vue—— 模块化开发 - webpack

vue webpack 起步配置loader

vue webpack 起步配置loader

Vue 3 和 webpack 5 - 错误:“模块属性已从依赖项中删除”