05、WebPack配置loader和插件plugins

Webpack

在 webpack 的配置中 loader 有两个目标:

  1. test 属性,用于标识出应该被对应的 loader 进行转换的某个或某些文件。
  2. use 属性,表示进行转换时,应该使用哪个 loader。
module: {
    rules: [
        {
            test: /\.css$/,
            use: [
                /* 使用多个loader时,从右向左读取 */
                {loader: "style-loader"},
                {loader: "css-loader"}
            ]
        }
    ]
}

“嘿,webpack 编译器,当你碰到「在 require()/import 语句中被解析为 '.css' 的路径」时,在你对它打包之前,先使用 css-loader 转换一下。”

1、图片文件的处理

安装开发时依赖

npm install --save-dev url-loader

当图片大小小于limit限制时,会将图片编译为base64的字符串形式。

当图片大小大于limit限制时,npm run build,会报错。没有找到file-loader。

安装开发时依赖

npm install --save-dev file-loader

代码:

body {
  /*background-color: greenyellow;*/
  background: url("../img/wallhaven-r2ewxq.jpg");
}
/* 配置入口和出口CommonJS语法 */
const path = require("path")
module.exports = {
  entry: './src/main.js',
  /* output是一个对象,path属性(动态绑定,调用path模块,npm init)和filename属性 */
  output: {
    path: path.resolve(__dirname, 'dist'), /* resolve用于拼接路径 */
    filename: 'my-webpack-bundle.js',
    publicPath: './dist/'
  },
  /* 配置css-loader */
  module: {
    rules: [
      /* css文件 */
      {
        test: /\.css$/,
        use: [
          /* 使用多个loader时,从右向左读取 */
          {loader: "style-loader"},
          {loader: "css-loader"}
        ]
      },
      /* 图片文件 */
      {
        test: /\.(png|jpg|gif)$/,
        use: [
          {
            loader: 'url-loader',
            options: {
              /*limit: 8192*/
              /* 当加载的图片大小小于limit时,会将图片编译成base64的字符串形式 */
              /*limit: 800000*/
              /* 当加载的图片大小大于limit时,npm run build会报错,如果大于需要使用file-loader */
              /*
              ERROR in ./src/img/wallhaven-r2ewxq.jpg
              Module build failed: Error: Cannot find module 'file-loader'
               */
              limit: 700000,
              /* 打包到dist文件夹,在output下增加publicPath属性 */
              /* 给生成的图片设置名称,ext使用图片以前的扩展名 */
              name: 'img/[name].[hash:8].[ext]'
            },
          }
        ]
      }
    ]
  }
}
{
  "name": "imgfile",
  "version": "1.0.0",
  "description": "",
  "main": "webpack.config.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "build": "webpack"
  },
  "author": "lwj",
  "license": "ISC",
  "devDependencies": {
    "css-loader": "^3.5.3",
    "file-loader": "^6.0.0",
    "style-loader": "^1.2.0",
    "url-loader": "^4.1.0",
    "webpack": "^3.6.0"
  }
}

2、ES6转ES5的babel

前面的代码中,使用Webpack生成的bundle.js文件中存在ES6的代码。

如果希望将ES6的语法转为ES5,更好的在浏览器运行,那么就需要使用babel。

在Webpack中,我们直接使用babel对应的loader。

npm install --save-dev babel-loader@7 babel-core babel-preset-es2015
const path = require("path")
module.exports = {
  entry: './src/main.js',
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'my-webpack-bundle.js',
    publicPath: './dist/'
  },
  module: {
    rules: [
      /* es6转es5 */
      {
        test: /\.js$/,
        /* 排除 */
        exclude: /(node_modules|bower_components)/,
        use: {
          loader: 'babel-loader',
          options: {
            presets: ['es2015']
          }
        }
      }
    ]
  }
}

这样,即使客户使用的是较低版本的浏览器,也是支持的。

3、使用Vue的配置过程

现在我们希望在项目中使用Vuejs,那么必须需要对其有依赖,所以需要先进行安装。

注意:

因为我们在后续实际项目中也是需要Vue的,所以安装时并不是开发时依赖。

npm install vue --save

刚开始学习Vue,都是通过script标签引入源码的方式,它不是通过模块化的方式管理Vue的,既然Webpack支持模块化,那么可以将Vue作为模块安装。

安装Vue的三种方式:

  • 直接下载,通过script标签引入;
  • CDN引入;
  • npm安装。

1、runtime-only

代码中不可以有任何的template,

2、runtime-compiler

代码中可以有template。

webpack.config.js

const path = require("path")
module.exports = {
  resolve: {
    alias: {
      'vue$': 'vue/dist/vue.esm.js'
    }
  }
}

main.js

/* 安装vue模块npm install vue --save */
import Vue from 'vue'

const app = new Vue({
  el: '#app',
  data: {
    message: 'Hello Webpack'
  },
  methods: {

  }
});

index.html

<body>
<div id="app">
  <span>{{message}}</span>
</div>

<script src="./dist/my-webpack-bundle.js"></script>
</body>

4、使用Vue的终极方案

SPA(Single Page Application)单页面应用:只有一个html页面(固定的)。

如果是多页面,通过路由vue-router。

由于.vue是特殊的文件格式,和css、图片格式一样,都需要loader。

npm install vue-loader vue-template-compiler --save-dev

Vue Loader的配置与其他加载器有些不同。除了适用vue-loader于所有带有扩展名的文件的规则外,请.vue确保将Vue Loader的插件添加到您的webpack配置中:

// webpack.config.js
const VueLoaderPlugin = require('vue-loader/lib/plugin')

module.exports = {
  module: {
    rules: [
      // ... other rules
      {
        test: /\.vue$/,
        loader: 'vue-loader'
      }
    ]
  },
  plugins: [
    // make sure to include the plugin!
    new VueLoaderPlugin()
  ]
}

全部代码:

index.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>
<div id="app">

</div>

<script src="./dist/my-webpack-bundle.js"></script>
</body>
</html>

package.json

{
  "name": "imgfile",
  "version": "1.0.0",
  "description": "",
  "main": "webpack.config.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "build": "webpack"
  },
  "author": "lwj",
  "license": "ISC",
  "devDependencies": {
    "babel-core": "^6.26.3",
    "babel-loader": "^7.1.5",
    "babel-preset-es2015": "^6.24.1",
    "css-loader": "^3.5.3",
    "file-loader": "^6.0.0",
    "style-loader": "^1.2.0",
    "url-loader": "^4.1.0",
    "vue-loader": "^15.9.1",
    "vue-template-compiler": "^2.6.11",
    "webpack": "^3.6.0"
  },
  "dependencies": {
    "vue": "^2.6.11"
  }
}

main.js

let {sum, mul} = require('./js/mathutils');

console.log(sum(12, 13));
console.log(mul(12, 12));

require('./css/normal');

/* 安装vue模块npm install vue --save */
import Vue from 'vue'
import App from './vue/App'

new Vue({
  el: '#app',
  template: '<App></App>',
  components: {
    /* ES6:如果对象名和值一样,可以写一个 */
    App,
  }
});

App.vue

<template>
  <div>
    <span class="title">{{message}}</span>
    <button v-on:click="btnClick">按钮</button>
    <span>{{name}}</span>
  </div>
</template>

<script>
  export default {
    name: "App",
    data() {
      return {
        message: 'Hello Webpack',
        name: 'ShawnYue'
      }
    },
    methods: {
      btnClick() {
        console.log('btnClick');
      }
    }
  }
</script>

<style scoped>
  .title {
    color: yellowgreen;
  }
</style>

webpack.config.js

/* 配置入口和出口CommonJS语法 */
const VueLoaderPlugin = require("vue-loader/lib/plugin")
const path = require("path")
module.exports = {
  entry: './src/main.js',
  /* output是一个对象,path属性(动态绑定,调用path模块,npm init)和filename属性 */
  output: {
    path: path.resolve(__dirname, 'dist'), /* resolve用于拼接路径 */
    filename: 'my-webpack-bundle.js',
    publicPath: './dist/'
  },
  module: {
    rules: [
      /* css文件 */
      {
        test: /\.css$/,
        use: [
          /* 使用多个loader时,从右向左读取 */
          {loader: "style-loader"},
          {loader: "css-loader"}
        ]
      },
      /* 图片文件 */
      {
        test: /\.(png|jpg|gif)$/,
        use: [
          {
            loader: 'url-loader',
            options: {
              /*limit: 8192*/
              /* 当加载的图片大小小于limit时,会将图片编译成base64的字符串形式 */
              /*limit: 800000*/
              /* 当加载的图片大小大于limit时,npm run build会报错,如果大于需要使用file-loader */
              /*
              ERROR in ./src/img/wallhaven-r2ewxq.jpg
              Module build failed: Error: Cannot find module 'file-loader'
               */
              limit: 700000,
              /* 打包到dist文件夹,在output下增加publicPath属性 */
              /* 给生成的图片设置名称,ext使用图片以前的扩展名 */
              name: 'img/[name].[hash:8].[ext]'
            },
          }
        ]
      },
      /* es6转es5 */
      {
        test: /\.js$/,
        /* 排除 */
        exclude: /(node_modules|bower_components)/,
        use: {
          loader: 'babel-loader',
          options: {
            presets: ['es2015']
          }
        }
      },
      /* vue文件 */
      {
        test: /\.vue$/,
        use: [
          {loader: 'vue-loader'}
        ]
      }
    ]
  },
  plugins: [
    new VueLoaderPlugin(),
  ],
  resolve: {
    /* 在import/require时可以省略后缀名 */
    extensions: ['.js', '.vue', '.css'],
    alias: {
      'vue$': 'vue/dist/vue.esm.js'
    }
  }
}

5、横幅plugin

Webpack中的插件就是对Webpack现有功能的各种扩展,比如打包优化,文件压缩等。

loader和plugin的区别:

  • loader主要用于转换某些类型的模块,它是一个转换器;
  • plugin是插件,它是对webpack本身的扩展,是一个扩展器。

plugin的使用过程:

  • 通过npm安装需要使用的插件,(某些webpack已经内置的插件不需要安装);
  • 在webpack.config.js的plugins中配置插件。

添加版权的Plugin

该插件名称为BannerPlugin,属于webpack自带的插件。

const VueLoaderPlugin = require("vue-loader/lib/plugin")
const path = require("path")
const webpack = require("webpack")
module.exports = {
  plugins: [
    new VueLoaderPlugin(),
    new webpack.BannerPlugin('最终版权归lwj所有.'),
  ]
}

重新打包,查看bundle.js文件。

6、HtmlWebpackPlugin

目前我们的index.html文件是存放在项目的根目录下的。

  • 我们知道在真实发布项目时,发布的是dist文件夹下的内容,所以我们需要将index.html文件打包到dist文件夹中,这个时候就可以使用HtmlWebpackPlugin插件;

HtmlWebpackPlugin可以为我们做:

  • 自动生成一个index.html;
  • 将打包的js文件,自动通过script标签插入到body中。

安装插件:

npm install html-webpack-plugin --save-dev
"html-webpack-plugin": "^3.2.0",

现在不需要publicpath属性去dist目录下了,所以注释。

项目目录下的index.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>
<div id="app">

</div>
</body>
</html>

main.js

import Vue from 'vue'
import App from './vue/App'
require("./css/normal")

new Vue({
  el: '#app',
  template: '<App></App>',
  components: {
    /* ES6:如果对象名和值一样,可以写一个 */
    App,
  }
});

App.vue

<template>
  <div>
    <span class="title">{{message}}</span>
    <button v-on:click="btnClick">按钮</button>
    <span>{{name}}</span>
  </div>
</template>

<script>
  export default {
    name: "App",
    data() {
      return {
        message: 'Hello Webpack',
        name: 'ShawnYue'
      }
    },
    methods: {
      btnClick() {
        console.log('btnClick');
      }
    }
  }
</script>

<style scoped>
  .title {
    color: yellowgreen;
  }
</style>

webpack.config.js

const VueLoaderPlugin = require("vue-loader/lib/plugin")
const path = require("path")
const webpack = require("webpack")
const HtmlWebpackPlugin = require("html-webpack-plugin")
module.exports = {
  entry: './src/main.js',
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'my-webpack-bundle.js',
  },
  module: {
    rules: [
      {
        test: /\.css$/,
        use: [
          {loader: "style-loader"},
          {loader: "css-loader"}
        ]
      },
      {
        test: /\.(png|jpg|gif)$/,
        use: [
          {
            loader: 'url-loader',
            options: {
              limit: 700000,
              name: 'img/[name].[hash:8].[ext]'
            },
          }
        ]
      },
      /* es6转es5 */
      {
        test: /\.js$/,
        /* 排除 */
        exclude: /(node_modules|bower_components)/,
        use: {
          loader: 'babel-loader',
          options: {
            presets: ['es2015']
          }
        }
      },
      /* vue文件 */
      {
        test: /\.vue$/,
        use: [
          {loader: 'vue-loader'}
        ]
      }
    ]
  },
  plugins: [
    new VueLoaderPlugin(),
    new webpack.BannerPlugin('最终版权归lwj所有.'),
    new HtmlWebpackPlugin({
      /* 根据此模板生成dist文件夹下的index.html,然后自动导入打包后的js文件 */
      template: 'index.html',
    })
  ],
  resolve: {
    extensions: ['.js', '.vue', '.css'],
    alias: {
      'vue$': 'vue/dist/vue.esm.js'
    }
  }
}

重新打包发布,自动生成的index.html。

7、对JS文件进行压缩

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

  • 这里我们对打包的js文件进行压缩
  • 我们使用第三方插件uglifyjs-webpack-plugin,并且指定版本号1.1.1,和CLI2保持一致。
npm install [email protected] --save-dev
plugins: [
    new VueLoaderPlugin(),
    new webpack.BannerPlugin('最终版权归lwj所有.'),
    new HtmlWebpackPlugin({
        /* 根据此模板生成dist文件夹下的index.html,然后自动导入打包后的js文件 */
        template: 'index.html',
    }),
    new uglifyjsWebpackPlugin(),
],

重新打包。

bundle.js从原来的360KB压缩到130KB。

8、webpack-dev-server搭建本地服务器

在webpack中使用之前需要先安装它

npm install --save-dev [email protected]

配置

devServer: {
    contentBase: './dist',
    inline: true
}

不再通过npm run build,而是

或者

"scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "build": "webpack",
    "dev": "webpack-dev-server"
},

通过配置脚本,执行npm run dev,首先在本地下面找。

通过npm run dev命令后的链接

,点击链接,可以在本地修改代码,浏览器自动刷新,显示结果。

最终,npm run build打包。

"scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "build": "webpack",
    "dev": "webpack-dev-server --open"
},

--open:自动打开浏览器。

9、配置文件分离

开发时配置 和 编译打包时的配置

猜你喜欢

转载自www.cnblogs.com/shawnyue-08/p/12793727.html