Vue和Webpack、loader、plugin详解

本质上,webpack 是一个现代 JavaScript 应用程序的静态模块打包器(module bundler)。

(一) 安装Webpack

  • 安装webpack首先要安装Node.js(版本大于9.0),Node.js自带了软件包管理工具npm

  • 查看自己的node版本: node -v

  • 全局安装webpack(版本号为3.6.0,因为vue cli2依赖该版本)(一般不建议全局安装)(如果想安装最新版本的webpack则不需要加上 @3.6.0)

    #检查自己是否安装了webpack
    webpack --version
    #如果没有安装则运行下边代码,梯子安装更快捷
    npm install webpack@3.6.0 webpack-cli -g
    
  • 局部安装webpack(如果想安装最新版本的webpack则不需要加上 @3.6.0)

    #进入到对应的项目文件后运行如下代码
    npm install webpack@3.6.0 webpack-cli --save-dev
    

(二) Webpack的起步

  1. 该部分最终的目录结构
    在这里插入图片描述

  2. 在项目文件夹中的控制台中执行如下代码,创建 package.json 文件,用于管理项目的信息、库依赖等

    # 也可以使用npm init -y  ,将不会出现图片所示的选项
    npm init
    

    在这里插入图片描述

  3. 在项目文件夹中的控制台中运行如下代码安装 webpack, 安装后在项目文件夹中将会生成一个 node_modules 文件夹

    npm install webpack@3.6.0 webpack-cli -D
    
  4. 在src文件夹中 新建三个文件

  • [1]. index.js

    // 1.使用commonjs的模块化规范 导入common-js-test.js文件中的 job、userTool 变量 与 getJob、sum 方法
    const { job, userTool, getJob, sum } = require("./common-js-test.js");
    console.log('job: ' + job);
    console.log('userTool: ' + userTool);
    console.log('getJob:' + getJob());
    console.log('sum:' + sum());
    
    // 2.使用ES6的模块化的规范 导入 module-test.js 文件中的 age 变量 与 add 、getAge方法
    //  module-test.js 文件中未命名的方法,在这里将被命名为 mulNum
    // 如果 module-test.js 文件 只导出 一个未命名的方法,则可以使用: import mulNum from './module-test.js', 来导出该方法
    import { age, add, getAge, default as mulNum } from "./module-test.js";
    
    console.log('age:' + age);
    console.log('add:' + add(5, 5));
    console.log('mulNum: ' + mulNum(8, 5));
    
  • [2].common-js-test.js

    // commonjs 方式导出变量与方法
    const job = '程序员'
    
    const getJob = function () {
      return '工作为:' + job
    }
    
    module.exports = {
      userTool: 'webpack',  // 也可以在这里定义 userTool 变量 
      sum: function(){ return 1 + 1} , // 也可以在这里定义 sum 方法 
      job,
      getJob: getJob
    }
    
  • [3].module-test.js

    //写法1: 导出 age 变量 与 add 方法,可以同时导出多个
    const age = 32
    const add = function (a, b) { return a + b }
    export { age, add }
    
    //写法2:导出一个不命名的方法,导入时进行命名,只能导出自己
    //同一个文件中只能有一个 default 
    export default function (a, b) { return a * b }
    
    //写法3:导出 getAge 方法,只能导出自己
    export const getAge = function (a, b) { return '获取age:' + age }
    
  1. 在控制台中进入到在项目所在的目录下(即index.html所在的目录),然后使用如下命令,在 dist 文件中生成 main.js

     #与下边命令等价:
     #高版本webpack使用:npx webpack --entry ./src/index.js --output-path ./dist --mode=development
     #低版本webpack使用:
     npx webpack --entry ./src/index.js  ./dist/index.js
    
  2. 在 index.html 中引入 main.js 文件

    <script src="dist/main.js"></script>
    
  3. 在浏览器中打开index.html文件即可看到运行结果。

(三) Webpack的配置

[1].webpack.config.js配置

最终的文件夹结构
在这里插入图片描述

  1. 一直在控制台中输入 npx webpack 源文件 目标文件 命令来打包js文件,会觉得不方便,这时可以配置webpack 来方便使用。
  2. 在项目根目录下创建一个 webpack.config.js 文件 (名字固定) ,设置本项目的配置文件, 如果此时直接在终端中输入“webpack”,会报一个路径不对的错误。所以需要使用node来获取路径。
    //使用node获取项目路径,require("path")中的path会从node的包里边找,所以要创建node包
    const path = require("path");
    
    module.exports = {
        //对应的入口
        entry: './src/index.js',
        //对应的出口
        output: {
            //path要写为绝对路径
            path: path.resolve(__dirname, 'dist'), //__dirname是node保存的当前文件夹的绝对路径
            filename: 'bundle.js'
        },
    }
    
  3. 在控制台中输入 npx webpack 执行打包,将在 dist 文件夹中就会生成 bundle.js文件。

[2].package.json配置

  1. npx webpack 命令映射到 npm run build。

  2. 在package.json文件中有一个“scripts”属性,可以映射脚本。在“scripts”中添加"build": “webpack”

    "scripts": {
        "test": "echo \"Error: no test specified\" && exit 1",
        "build": "webpack"
      },
    
  3. 在终端中输入如下代码,就可以实现webpack功能。

    npm run build
    
  4. 在“scripts”中的代码执行时,优先使用的是当前项目配置的webpack,然后没找到时才使用全局配置的webpack。

(四) webpack中loader的使用

  • 在开发中我们不仅仅有基本的js代码处理,我们也需要加载css、图片,也包括一些高级的将ES6转成ES5代码,将TypeScript转成ES5代码,将scss、less转成css,将.jsx、.vue文件转成js文件等等。对于webpack本身的能力来说,对于这些转化是不支持的。给webpack扩展对应的loader就可以啦。
  • https://www.webpackjs.com/loaders/#%E6%A0%B7%E5%BC%8F

[1].css-loader加载css文件

  • style-loader 将模块的导出作为样式添加到 DOM 中
  • css-loader只负责将css文件进行加载。
  • 文件结构,其中main.js负责引入info.js、mathUtils.js和common.css文件,在main.js中引入css文件使用 require(“./css/common.css”); 代码
    在这里插入图片描述
  1. 安装style-loader

    npm install style-loader --save-dev
    
  2. 安装css-loader

    npm install --save-dev css-loader
    
  3. 在入口文件中引入css文件,(这里还是在main.js文件中引入,main.js作为src的入口文件)

    require("./css/common.css");
    
  4. 配置webpack.config.js 文件,为module.exports 添加module属性。

    module.exports = {
      module: {
        rules: [
          {
            test: /\.css$/,
            //系统读取use的值时是从右向左读
            use: ['style-loader','css-loader']
          }
        ]
      }
    }
    
  5. 开始打包
    进入到项目根目录,然后执行如下代码

    webpack ./src/main.js ./dis/bundle.js
    

[2].url-loader加载img

  • 在css文件中如果使用到了图片需要添加url-loader
  1. 安装url-loader

    npm install --save-dev url-loader
    
  2. 配置webpack.config.js文件

    module.exports = {
        module: {
    	    rules: [
    	    //这个是css-loader的配置
    	      {
    	        test: /\.css$/,
    	        use: ['style-loader','css-loader' ]
            },
            //这个是url-loader的配置
            {
              test: /\.(png|jpg|gif)$/,
              use: [
                {
                  loader: 'url-loader',
                  options: {
                  //当加载的图片大小 小于limit时,会将图片编译成base64字符串形式
                  //如果大于limit时,会需要一个file-loader,直接安装file-loader就行,不需要配置
                    limit: 8192
                  }
                }
              ]
            }
    	  ]
    	}
    }
    
  3. 如果加载的图片的大小 大于设置的limit时

  • (1). 需要一个file-loader,直接安装file-loader就行,不需要配置。然后就会在导出文件的文件夹中有这个图片。此时图片的命名是一个32位的hash值。

    npm install --save-dev file-loader
    
  • (2). 这时虽然有这个图片但是生成后的页面中找不到该文件,这时需要设置webpack.config.js文件。在output中添加publicPath值为导出的文件夹

    module.exports = {
        //对应的入口
        entry: './src/main.js',
        //对应的出口
        output: {
            //path要写为绝对路径
            path: path.resolve(__dirname, 'dist'), //__dirname是node保存的当前文件夹的绝对路径
            filename: 'bundle.js',
            publicPath: "dist/"  //**** 添加这个 ******
        },
        module: {
    	    rules: [
    	      {
    	        test: /\.css$/,
    	        use: ['style-loader','css-loader' ]
            },
            {
              test: /\.(png|jpg|gif)$/,
              use: [
                {
                  loader: 'url-loader',
                  options: {
                    limit: 8192
                  }
                }
              ]
            }
    	    ]
    	  }
    }
    
  • (3). 如果不希望生成一个随机数的图片名字可以在webpack.config.js文件夹中的url-loader模块下的options属性下,添加name选项。

    use: [
     {
        loader: 'url-loader',
        options: {
          limit: 8192,
          //路径:因为已经设置了publicPath为:dist/,所以会在dist文件夹下创建路径中的文件夹
          //name要带中括号,这样就会将[name]当做一个变量,变量的值就是原来的图片的名字
          //[hash:8]取hash值的前八位
          //[ext]后缀
          name: "路径/[name].[hash:8].[ext]"	
        },
      }
    ]
    
  1. 开始打包

[3].babel-loader将ES6转为ES5

https://www.webpackjs.com/loaders/babel-loader/

  1. 将ES6的语法转为ES5,需要使用babel,在webpack中直接使用如下代码。

    npm install --save-dev babel-loader@7 babel-core babel-preset-es2015
    
  2. 配置webpack.config.js文件

    module: {
      rules: [
        {
          test: /\.js$/,
          //排除mode_modules、bower_components文件夹
          exclude: /(node_modules|bower_components)/,
          use: {
            loader: 'babel-loader',
            options: {
              presets: ['es2015']
            }
          }
        }
      ]
    }
    
  3. 开始打包

(五) Webpack中配置vue

  1. 安装vue,因为我们后续是在实际项目中也会使用vue的,所以并不是开发时依赖所以使用的--save而不是--save-dev。

    进入到项目根目录后执行下边的代码

    npm install vue --save
    
  2. 直接使用如下代码进行vue开发,会报一个如下的错误

     bundle.js:961 [Vue warn]: You are using the runtime-only build of Vue where the template compiler is not available. Either pre-compile the templates into render functions, or use the compiler-included build.
    
    //1. 引入vue
    import Vue from 'Vue'
    //2.开始写代码
    const app = new Vue({
        el:"#app",
        data: {
            message: "hello world!"
        }
    });
    
  3. 在webpack.config.js中module.exports配置一个属性resolve。(进行这一步的前提是进行了项目的webpack的安装,即局部安装看(一)节有)

    module.exports = {
        entry: './src/main.js',
        output: {  ... },
        module: { ... },
        resolve: {
          alias:{
          //含义:当js文件需要引入Vue时,会告诉js去node_modules/vue/dist/vue.esm.js路径下寻找
          //node_modules是局部的webpack文件夹
          //区分大小写
            'Vue$': 'vue/dist/vue.esm.js'
          }
    	}
    }
    
  4. 打包

(六) 使用template将HTML代码抽离

[1]. 使用template抽离html中的代码

  • 为了避免多次修改html文件中的vue信息,可以在Vue对象中添加template属性,将需要显示在html文件中的信息添加到template属性中

  • template属性中的代码在程序执行时,会被复制到 el 属性代表的Vue区域

    // 4.使用vue进行开发
    import Vue from 'Vue';
    
    const app = new Vue({
        el:"#app",
        template:`<h2>{{message}}</h2>`,
        data: {
            message: "hello world1!"
        }
    });
    

[2]. 使用组件抽离template中的html代码

  1. 创建组件

    const cpn = {
        template: `
            <div>
                <h2>{{message}}</h2>
                <button @click="btnClick">按钮</button>
            </div>
        `,
        data(){
            return {
                message: "hello world!"
            }
        },
        methods:{
            btnClick(){
                console.log('btnClick');
            }
        }
    }
    
  2. vue引用组件

    const app = new Vue({
        el:"#app",
        template:`<cpn />`,
        components:{
            cpn
        }
    });
    
  3. html文件中只有

    <div id="app">
    </div>
    
  4. 打包

[3]. 将组件从入口文件中抽离

  1. 将组件从入口函数中抽离出来,放在src文件夹的vue文件夹中,使用export default命令,为模块指定默认输出。

    export default {
        template: `
            <div>
                <h2>{{message}}</h2>
                <button @click="btnClick">按钮</button>
            </div>
        `,
        data(){
            return {
                message: "hello world!"
            }
        },
        methods:{
            btnClick(){
                console.log('btnClick1');
            }
        }
    }
    
  2. 在入口文件中引入组件,并命名为cpn

    import cpn from './vue/app.js'
    

(七) 使用.vue文件封装vue

[1]. 封装一个vue文件

  1. 创建一个app.vue文件
    文件结构为

    <template>
    	<!-- html结构 -->
    </template>
    
    <script>
    export default {
        //组件代码
    }
    </script>
    
    <style lang="stylus">
    	/*css样式*/
    </style>
    
  2. 在template标签中放入html模板

  3. 在script标签中创建vue组件

  4. 在style标签中创建样式

    <template>
        <div>
            <h2 class="myFont">{{message}}</h2>
            <button @click="btnClick">按钮</button>
        </div>
    </template>
    
    <script>
        export default {
            data(){
                return {
                    message: "hello world!"
                }
            },
            methods:{
                btnClick(){
                    console.log('btnClick2');
                }
            }
        }    
    </script>
    
    <style>
        .myFont{
            color:#fff;
        }
    </style>
    
  5. 配置Vue的loader

    npm install vue-loader vue-template-compiler --save-dev
    
  6. 在webpack.config.js中配置vue

    module: {
    	rules: [
    	    {
    	      test: /\.vue$/,
    	      use: ['vue-loader']
    	    }
    	]
    },
    
  7. 在package.json中查看“vue-loader”的版本,如果大于14.0版本需要安装一个VueLoaderPlugin的插件。
    这里直接将package.json中的“vue-loader”改为"^13.0.0",然后 运行

    npm install
    
  8. 开始打包

[2]. vue文件再加载一个vue文件

  1. 在一个vue文件中引入另一个vue文件

     import tpn from "./Tpn.vue"
    
  2. 注册引入的组件

    export default {
        name: 'App',
        data(){
            return {
                message: "hello world!"
            }
        },
        methods:{
            btnClick(){
                console.log('btnClick2');
            }
        },
        components:{
            tpn
        }
    } 
    
  3. 使用这个组件

    <template>
        <div>
            <tpn></tpn>
        </div>
    </template>
    

(八) plugin的使用

[1]. 打包html的plugin

当前的目录结构,发布项目是将dist文件夹中的文件放入到服务器中,但是index.html所在位置在项目的根目录下,这时也需要将index.html生成到dist文件中。
在这里插入图片描述

  • [1]. HtmlWebpackPlugin插件可以为我们做这些事情:

    • 自动生成一个index.html文件(可以指定模板来生成)
    • 将打包的js文件,自动通过script标签插入到body中
  • [2]. 安装HtmlWebpackPlugin(前提再该项目中已经安装了局部的webpack)

    //安装最新版本
    npm install html-webpack-plugin --save-dev
    
    //安装3.2.0版本,因为webpack版本低,而这个的版本高会出现不兼容的问题可能打包不上,所以要使用3.2.0版本
    npm install html-webpack-plugin@3.2.0 --save-dev
    
  • [3]. 修改webpack.config.js文件

    • 添加如下代码
      // 引入webpack基础组件
      const webpack = require("webpack");
      //引入html-webpack-plugin组件
      const HtmlWebPackPlugin = require("html-webpack-plugin");
      
      module.exports = {
          ...
          plugins: [
            new HtmlWebPackPlugin({
              template: "index.html"
            }),
          ]
      }
      
  • [4]. 如果webpack.config.js中有publicPath属性,要注释掉,将index.html文件中引入js、css的代码删掉

    <!-- 删掉如下代码 -->
    <script src="dist/bundle.js"></script>
    
  • [5]. 打包(如果按照上边的步骤,打包还出错,要安装3.2.0版本的HtmlWebpackPlugin)

  • [6]. 会在dist文件夹中生成各种后缀的文件

[2]. js压缩的Plugin

  1. 在项目发布之前,我们必然需要对js等文件进行压缩处理

  2. 使用一个第三方的插件uglifyjs-webpack-plugin,并且版本号指定1.1.1,和CLI2保持一致。

    npm install uglifyjs-webpack-plugin@1.1.1 --save-dev
    
  3. 修改webpack.config.js文件

    const uglifyJsPlugin = require("uglifyjs-webpack-plugin");
    
    module.exports = {
        ...
        plugins: [
          ...
          new uglifyJsPlugin()
        ]
    }
    
  4. 打包

(九) 搭建本地服务器

webpack提供了一个可选的本地开发服务器,这个本地服务器基于node.js搭建,内部使用express框架,可以实现我们想要的让浏览器自动刷新显示我们修改后的结果。

  1. 它是一个单独的模块,在webpack中使用之前需要先安装它

    npm install --save-dev webpack-dev-server@2.9.1
    
  2. 配置webpack.config.js文件

    module.exports = {
    	....
    	devServer:{
    		//为哪一个文件夹提供本地服务,默认是根文件夹,我们这里要填写./dist
    		contentBase: './dist',
    		//inline:页面实时刷新
    		inline: true
    		//port:端口号,默认8080
    		//historyApiFallback:在SPA页面中,依赖HTML5的history模式
    	}
    }
    
  3. 因为不是全局设置的服务器,所以需要使用下面的代码来使用局部的服务器

  • 第一种方案:
    node_modules\.bin\webpack-dev-server
    
  • 第二种方案:
    在package.json文件中的scripts属性下添加
"scripts": {
	//--open 在执行 npm run dev时可以自动打开,如果不想这样也可以不添加
    "dev":"webpack-dev-server --open"
  },
  1. 在浏览器中输入如下url即可。

     localhost:8080
    
  2. 修改组件文件可以直接显示在浏览器上,可能有点慢

(十) 对webpack.config.js进行拆分

  1. 因为webpack.config.js文件中的配置是将开发和生产环境的配置都放在了一起,可以将其进行拆分。

  2. 在项目目录下新建一个build文件夹,将webpack.config.js文件进行拆分,将公共部分放在一个文件,将开发配置放在一个文件中,将生产配置放在一个文件中。

  3. 为了使公共文件和其他文件进行合并,需要安装webpack-merge

    npm install wepack-merge --save-dev
    
  4. 例如:生产环境和公共文件的文件要进行合并在生产环境中添加如下代码。

    const webpackMerge = require("webpack-merge");
    //base.config就是公共配置文件
    const baseConfig = require('./base.config');
    module.exports = webpackMerge(baseConfig, {
    		//生产环境所需的配置放在这里
    });
    
  5. 这时就可以将项目目录下的webpack.config.js文件进行删除

  6. 如果直接使用"npm run build" (build是我的打包脚本名字。原型为:“build”:“webpack”) 会报一个找不到webpack.config.js文件的错误,这时需要修改package.json文件

    //指定配置文件所在的位置,prod.config.js是公共配置文件和生产环境配置文件合并后生成的文件
    “build”:"webpack --config ./build/prod.config.js"
    
  7. 注意在生成的prod.config.js文件时,里边的输出路径要进行更改

    module.exports = {
    	...
        output: {
            //path要写为绝对路径
            path: path.resolve(__dirname, '../dist'), //__dirname是node保存的当前文件夹的绝对路径
            filename: 'bundle.js'
        },
    }
    
  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值