webpack详解(再回顾)---vue学习过程

8 篇文章 0 订阅
4 篇文章 0 订阅

什么是Webpack?

webpack是一个现代的JavaScript应用的静态模块打包工具。

前端模块化

webpack其中一个核心就是让我们可能进行模块化开发,并且会帮助我们处理模块间的依赖关系。

而且不仅仅是JavaScript文件,我们的CSS、图片、json文件等等在webpack中都可以被当做模块来使用

打包如何理解呢?

就是将webpack中的各种资源模块进行打包合并成一个或多个包(Bundle)。并且在打包的过程中,还可以对资源进行处理,比如压缩图片,将scss转成css,将ES6语法转成ES5语法,将TypeScript转成JavaScript等等操作。

和grunt/gulp的对比

grunt/gulp的核心是Task

我们可以配置一系列的task,并且定义task要处理的事务(例如ES6、ts转化,图片压缩,scss转成css)

之后让grunt/gulp来依次执行这些task,而且让整个流程自动化。

所以grunt/gulp也被称为前端自动化任务管理工具。

什么时候用grunt/gulp呢?

如果你的工程模块依赖非常简单,甚至是没有用到模块化的概念。

只需要进行简单的合并、压缩,就使用grunt/gulp即可。

但是如果整个项目使用了模块化管理,而且相互依赖非常强,我们就可以使用更加强大的webpack了。

所以,grunt/gulp和webpack有什么不同呢?

grunt/gulp更加强调的是前端流程的自动化,模块化不是它的核心。

webpack更加强调模块化开发管理,而文件压缩合并、预处理等功能,是它附带的功能。

webpack的起步

我是直接根据以前的package.json安装的包 ,以前已经安装过了。(全局)

 webpack src/main.js -o build/built.js --mode=development

webpack 的配置、loader

一般都需要全局安装后再局部安装。由于我们的项目需要的版本不是全局的4点几的版本,

我在局部:npm i webpack@3.6.0 webpack-cli -D

而且在终端执行命令时,如果直接用webpack,那么使用的一定是全局的。

这时,我们可以在package.json里面配置scripts,

比如这里,npm run build 即等于执行webpack命令。

package.json中的scripts的脚本在执行时,会按照一定的顺序寻找命令对应的位置。 首先,会寻找本地的node_modules/.bin路径中对应的命令。 如果没有找到,会去全局的环境变量中寻找。

所以这样配置了,就可以解决使用局部的webpack.

style-loader,css-loader,less-loader,less

npm i css-loader style-loader --save-dev

npm i less@3.9.0 less-loader@4.1.0 -D(有时会因为版本问题报错,这里采用这个版本)

打包图片资源(我又因为版本问题出了好多错)

方法将"html-webpack-plugin"版本由 "^4.2.0"改为 "^3.2.0",

npm uninstall html-webpack-plugin

npm install html-webpack-plugin@3.2.0 -D

参照老师的教程,加什么publicPath:'build/',结果出错了。(想着这样才可以访问原来的图片)

我还是采用了以前学webpack4的时候,用html-webpack-plugin ,这样把原来的html文件作为模板加入到输出文件夹。并且它会自动引入导出的那个bundle.js文件。

// const path = require('path')
const {resolve}=require('path')
const HtmlWebpackPlugin=require('html-webpack-plugin')
module.exports = {
  entry: './src/main.js',
  output: {
    path: resolve(__dirname, 'build'),
    filename: 'bundle.js'
    //pulicPath:'build/'
  },
  module:{
    rules:[
      {
        test:/\.css$/,
        // css-loader只负责将css文件进行加载
        // style-loader负责将样式添加到DOM中
        // 使用多个loader时, 是从右向左
        use:['style-loader','css-loader']
      }
      ,{
        test:/\.less$/,
        use:['style-loader','css-loader','less-loader']
      },
      {
        test: /\.(png|jpg|gif|jpeg)$/,
        use: [
          {
            loader: 'url-loader',
            //loader:'file-loader',
            options: {
              // 当加载的图片, 小于limit时, 会将图片编译成base64字符串形式.
              // 当加载的图片, 大于limit时, 需要使用file-loader模块进行加载.
              limit: 13000,
              //esModule:false,
              name:'[hash:10].[ext]'
             //
             // name: 'img/[name].[hash:8].[ext]'
            },
          }
        ]
      }
      // },
      // {
      //   test:/\.html$/,
      //   loader:'html-loader'
      // }
     

    ]
  },
  plugins:[
    new HtmlWebpackPlugin({
      template:'./index.html'
    })
  ]
 
}

ES6语法处理

在前面我们说过,如果希望将ES6的语法转成ES5,那么就需要使用babel。

而在webpack中,我们直接使用babel对应的loader就可以了。

npm install --save-dev babel-loader@7 babel-core babel-preset-es2015

配置webpack.config.js

{
        test: /\.js$/,
        exclude: /(node_modules|bower_components)/,
        use: {
          loader: 'babel-loader',
          options: {
            presets: ['es2015']
          }
        }
      }

vue

npm install vue --save   (这里没有加-dev,加了-dev是开发时依赖但运行时不用依赖。然而我们的vue运行时需要依赖,所以就不加-dev了),然后为了学习,我的版本设置的与老师一样   npm i vue@2.5.21 --save

使用:

import Vue from 'vue'

原因:

解决:增加配置(module.exports里面)

 resolve: {
    // alias: 别名
    extensions: ['.js', '.css', '.vue'],
    alias: {
      'vue$': 'vue/dist/vue.esm.js'
    }
  }

 el和template区别(一)

如果我们希望将data中的数据显示在界面中,就必须是修改index.html 如果我们后面自定义了组件,也必须修改index.html来使用组件 但是html模板在之后的开发中,我并不希望手动的来频繁修改,是否可以做到呢

定义template属性:

在前面的Vue实例中,我们定义了el属性,用于和index.html中的#app进行绑定,让Vue实例之后可以管理它其中的内容

这里,我们可以在index.html中将div元素中的{{message}}内容删掉,只保留一个基本的id为div的元素

我们可以在main.js中再定义一个template属性,代码如下:

new Vue({
    el:'#app',
    template:`
    <div>
    <h2>嘻嘻嘻开心{{message}}</h2>
    </div>
    `,
    data:{
        message:'苹妹妹'
    }
})

el和template模板的关系是什么呢?

在我们之前的学习中,我们知道el用于指定Vue要管理的DOM,可以帮助解析其中的指令、事件监听等等。

而如果Vue实例中同时指定了template,那么template模板的内容会替换掉挂载的对应el的模板

这样做有什么好处呢?

这样做之后我们就不需要在以后的开发中再次操作index.html,只需要在template中写入对应的标签即可

Vue组件化开发引入

配置.vue模板

.vue文件封装处理

安装vue-loader和vue-template-compiler

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

报错了(我最开始的vue是2.5.21版本,与vue-template-compiler不一致),我在package.json里面更改,再npm i 重新安装,就成功了。

嘻嘻嘻,成功啦

代码展示:

main.js

import Vue from 'vue'

// 1.使用commonjs的模块化规范
const {add, mul} = require('./js/mathUtils.js')
require('./css/normal.css')

console.log(add(20, 30));
console.log(mul(20, 30));

// 2.使用ES6的模块化的规范
import {name, age, height} from "./js/info";

console.log(name);
console.log(age);
console.log(height);
// 4.依赖less文件
require('./css/special.less')
document.writeln('<h2>你好啊,小苹苹!</h2>')

import App from './vue/App.vue'

new Vue({
    el:'#app',
    template:`
    <App/>
    `,
   components:{
       App
   }
})

 App.vue

<template>
  <div >
      <h2 class="title">{{message}}</h2>
      <button>按钮</button>
      <h2>{{name}}</h2>
      <Cpn/>
</div>
</template>

<script>
 import Cpn from './Cpn.vue'
export default {
  name:"App",
  components:{},
  props:{},
  data(){
    return {
        message:"hello vue+webpack",
        name:'ppqq'
    }
  },
  watch:{},
  computed:{},
  methods:{},
  created(){},
  mounted(){}
}
</script>
<style  scoped>
    .title{
        color:greenyellow;
    }
</style>

Cpp.vue

<template>
  <div >
      <h2>我是cpn的标题</h2>
      <h2>{{name}}}</h2>
</div>
</template>

<script>
export default {

  name:"Cpn",
  components:{},
  props:{},
  data(){
    return {
        name:'CPN组件的name'
    }
  },
  watch:{},
  computed:{},
  methods:{},
  created(){},
  mounted(){}
}
</script>
<style  scoped>
</style>

webpack.config.js

// const path = require('path')
const {resolve}=require('path')
const HtmlWebpackPlugin=require('html-webpack-plugin')
module.exports = {
  entry: './src/main.js',
  output: {
    path: resolve(__dirname, 'build'),
    filename: 'bundle.js'
    //pulicPath:'build/'
  },
  module:{
    rules:[
      {
        test:/\.css$/,
        // css-loader只负责将css文件进行加载
        // style-loader负责将样式添加到DOM中
        // 使用多个loader时, 是从右向左
        use:['style-loader','css-loader']
      }
      ,{
        test:/\.less$/,
        use:['style-loader','css-loader','less-loader']
      },
      {
        test: /\.(png|jpg|gif|jpeg)$/,
        use: [
          {
            loader: 'url-loader',
            //loader:'file-loader',
            options: {
              // 当加载的图片, 小于limit时, 会将图片编译成base64字符串形式.
              // 当加载的图片, 大于limit时, 需要使用file-loader模块进行加载.
              limit: 13000,
              //esModule:false,
              name:'[hash:10].[ext]'
             //
             // name: 'img/[name].[hash:8].[ext]'
            },
          }
        ]
      },
      {
        test: /\.js$/,
        exclude: /(node_modules|bower_components)/,
        use: {
          loader: 'babel-loader',
          options: {
            presets: ['es2015']
          }
        }
      },
      {
        test:/\.vue$/,
        use:['vue-loader']
      }
      // },
      // {
      //   test:/\.html$/,
      //   loader:'html-loader'
      // }
     

    ]
  },
  plugins:[
    new HtmlWebpackPlugin({
      template:'./index.html'
    })
  ],
  resolve: {
    // alias: 别名
    extensions: ['.js', '.css', '.vue'],
    alias: {
      'vue$': 'vue/dist/vue.esm.js'
    }
  }
 
}

plugin

plugin是插件的意思,通常是用于对某个现有的架构进行扩展。 webpack中的插件,就是对webpack现有功能的各种扩展,比如打包优化,文件压缩等等

loader和plugin区别

loader主要用于转换某些类型的模块,它是一个转换器。

plugin是插件,它是对webpack本身的扩展,是一个扩展器。

plugin的使用过程:

步骤一:通过npm安装需要使用的plugins(某些webpack已经内置的插件不需要安装)

步骤二:在webpack.config.js中的plugins中配置插件。

添加版权的Plugin

该插件名字叫BannerPlugin,属于webpack自带的插件。

打包html的plugin

我们需要将index.html文件打包到dist文件夹中,这个时候就可以使用HtmlWebpackPlugin插件

HtmlWebpackPlugin插件可以为我们做这些事情:

自动生成一个index.html文件(可以指定模板来生成)

将打包的js文件,自动通过script标签插入到body中

下载:npm install html-webpack-plugin --save-dev

js压缩的Plugin

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

下载:npm install uglifyjs-webpack-plugin@1.1.1 --save-dev

配置:

const webpack = require('webpack')

const HtmlWebpackPlugin = require('html-webpack-plugin')

const UglifyjsWebpackPlugin = require('uglifyjs-webpack-plugin')
.......其余省略

 plugins:[

    new webpack.BannerPlugin('最终版权归zlppassion所有'),

    new HtmlWebpackPlugin({

      template:'./index.html'

    }),

    new UglifyjsWebpackPlugin()

  ]

 

搭建本地服务器

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

npm install --save-dev webpack-dev-server@2.9.3

这里的版本是与webpack3.6.0和cli2 相匹配的一个版本

devserver也是作为webpack中的一个选项,选项本身可以设置如下属性:

contentBase:为哪一个文件夹提供本地服务,默认是根文件夹,我们这里要填写./build

port:端口号

inline:页面实时刷新

historyApiFallback:在SPA页面中,依赖HTML5的history模式

package.json里面的配置,加了--open就可以自动跳转到浏览器显示了。

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

webpack.config.js的配置

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

执行命令npm run dev即可。

webpack配置分离

意思就是最好分一下工

 

base.config.js里面放共有的,dev.config.js里面放开发时用的,而prod.config.js放生产时用的。

安装:

npm install webpack-merge --save-dev

当三个js文件都写好后,之前的webpack.config.js就可以删掉了。但是运行前先记得配置package.json里面的scripts.

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

 因为默认是执行webpack.config.js的

代码:

base.config.js

const path = require('path')
const webpack = require('webpack')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const UglifyjsWebpackPlugin = require('uglifyjs-webpack-plugin')

module.exports = {
  entry: './src/main.js',
  output: {
    path: path.resolve(__dirname, '../dist'),
    filename: 'bundle.js',
    // publicPath: 'dist/'
  },
  module: {
    rules: [
      {
        test: /\.css$/,
        // css-loader只负责将css文件进行加载
        // style-loader负责将样式添加到DOM中
        // 使用多个loader时, 是从右向左
        use: [ 'style-loader', 'css-loader' ]
      },
      {
        test: /\.less$/,
        use: [{
          loader: "style-loader", // creates style nodes from JS strings
        }, {
          loader: "css-loader" // translates CSS into CommonJS
        }, {
          loader: "less-loader", // compiles Less to CSS
        }]
      },
      {
        test: /\.(png|jpg|gif|jpeg)$/,
        use: [
          {
            loader: 'url-loader',
            options: {
              // 当加载的图片, 小于limit时, 会将图片编译成base64字符串形式.
              // 当加载的图片, 大于limit时, 需要使用file-loader模块进行加载.
              limit: 13000,
              name: 'img/[name].[hash:8].[ext]'
            },
          }
        ]
      },
      {
        test: /\.js$/,
        // exclude: 排除
        // include: 包含
        exclude: /(node_modules|bower_components)/,
        use: {
          loader: 'babel-loader',
          options: {
            presets: ['es2015']
          }
        }
      },
      {
        test: /\.vue$/,
        use: ['vue-loader']
      }
    ]
  },
  resolve: {
    // alias: 别名
    extensions: ['.js', '.css', '.vue'],
    alias: {
      'vue$': 'vue/dist/vue.esm.js'
    }
  },
  plugins: [
    new webpack.BannerPlugin('最终版权归aaa所有'),
    new HtmlWebpackPlugin({
      template: 'index.html'
    })
  ]
}

 dev.config.js

const webpackMerge = require('webpack-merge')
const baseConfig = require('./base.config')

module.exports = webpackMerge(baseConfig, {
  devServer: {
    contentBase: './dist',
    inline: true
  }
})

prod.config.js

const UglifyjsWebpackPlugin = require('uglifyjs-webpack-plugin')
const webpackMerge = require('webpack-merge')
const baseConfig = require('./base.config')

module.exports = webpackMerge(baseConfig, {
  plugins: [
    new UglifyjsWebpackPlugin()
  ]
})


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值