Vue_Webpack详解

举报
Studying-swz 发表于 2022/08/20 16:42:42 2022/08/20
【摘要】 @TOC 1.认识webpackwebpack是一个现代的JavaScript应用的静态模块打包工具1.模块化在ES6之前,我们要想进行模块化开发,就必须借助于其他的工具,让我们可以进行模块化开发。并且在通过模块化开发完成了项目后,还需要处理模块间的各种依赖,并且将其进行整合打包。 而webpack其中一个核心就是让我们可能进行模块化开发,并且会帮助我们处理模块间的依赖关系。而且不仅仅是Ja...

@TOC

1.认识webpack

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

  • 1.模块化

    • 在ES6之前,我们要想进行模块化开发,就必须借助于其他的工具,让我们可以进行模块化开发。
    • 并且在通过模块化开发完成了项目后,还需要处理模块间的各种依赖,并且将其进行整合打包。 而webpack其中一个核心就是让我们可能进行模块化开发,并且会帮助我们处理模块间的依赖关系。
    • 而且不仅仅是JavaScript文件,我们的CSS、图片、json文件等等在webpack中都可以被当做
  • 2.打包

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

    • 如果你的工程模块依赖非常简单,甚至是没有用到模块化的概念。
    • 只需要进行简单的合并、压缩,就使用grunt/gulp即可。
    • 但是如果整个项目使用了模块化管理,而且相互依赖非常强,我们就可以使用更加强大的webpack
      在这里插入图片描述

2.webpack的安装

  • 安装node.js(https://nodejs.org/zh-cn/
  • 查看node版本 node -v
  • 全局安装webpack npm install webpack@3.6.0 -g,指定了版本为3.6.0
  • 局部安装webpack cd 对应目录;npm install webpack@3.6.0 --save-dev
  • 其中--save-dev是开发时依赖,项目打包后不需要继续使用
  • 为什么全局安装后,还需要局部安装呢?
    • 在终端直接执行webpack命令,使用的全局安装的webpack
    • 当在package.json中定义了scripts时,其中包含了webpack命令,那么使用的是局部webpack

3.webpack的起步

  • 创建目录结构
    在这里插入图片描述

  • 文件和文件夹解析:

    • dist文件夹:用于存放之后打包的文件
    • src文件夹:用于存放我们写的源文件
      • main.js:项目的入口文件。
      • mathUtils.js:定义了一些数学工具函数,可以在其他地方引用,并且使用。
      • info.js:定义了一些变量信息
    • index.html:浏览器打开展示的首页html
    • package.json:通过npm init生成的,npm包管理的文件
  • mathUtils.js

    function add(num1,num2){
        return num1 + num2;
    }
    
    function mul(num1,num2){
        return num1*num2;
    }
    
    module.exports = {
        add,
        mul
    }
    
  • info.js

    export const name = 'why';
    export const height = 180;
    
  • main.js

    const {add,mul} = require('./mathUtils.js');
    
    console.log(add(20,30));
    console.log(mul(20,30));
    
    import {name,height} from './info.js';
    console.log(name);
    console.log(height);
    

    注:可以看到main.js引入了其它js文件

  • webpack打包

    webpack ./src/main.js ./dist/bundle.js
    
  • 打包后会在dist文件下,生成一个bundle.js文件

  • bundle.js文件,是webpack处理了项目直接文件依赖后生成的一个js文件,我们只需要将这个js文件在index.html中引入即可

  • index.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
    </head>
    <body>
     
    <script src="dist/bundle.js"></script>
    </body>
    </html>
    

4.webpack的配置

  • 目标:简化上面的打包命令

  • 1.创建webpack.config.js文件

    const path = require('path')
    
    module.exports = {
        entry : "./src/main.js",
        output: {
            path: path.resolve(__dirname,'dist'), //动态获取绝对路径,__dirname是node中全局变量
            filename :  "bundle.js"
        },
    }
    
  • 2.npm init,生成package.json文件,这里面是针对当前项目的主要描述文件(里面会生成所有安装的依赖)

    在这里插入图片描述

  • 3.局部安装webpack----cd 当前目录;npm install webpack@3.6.0 --save-dev,生成node模块
    在这里插入图片描述

  • 4.配置package.json文件,简化命令
    在这里插入图片描述

  • 5.命令npm run build

5.loader的使用

  • 在开发中我们不仅仅有基本的js代码处理,我们也需要加载css、图片,也包括一些高级的将ES6转成ES5代码,将TypeScript转成ES5代码,将scss、less转成css,将.jsx、.vue文件转成js文件等等
  • 对于webpack本身的能力来说,对于这些转化是不支持的。需要webpack扩展对应的loader
  • loader使用过程:
    • 步骤一:通过npm安装需要使用的loader
    • 步骤二:在webpack.config.js中的modules关键字下进行配置

5.1 css的loader使用

  • 1.创建css文件
    在这里插入图片描述

    body {
        background-color:red; 
    }
    
  • 2.main.js引用

    //1.使用commonjs的模块化规范
    const {add,mul} = require('./js/mathUtils.js');
    
    console.log(add(20,30));
    console.log(mul(20,30));
    
    //2.使用ES6的模块化规范
    import {name,height} from './js/info.js';
    console.log(name);
    console.log(height);
    
    
    //3.依赖css文件
    require("./css/normal.css")
    
  • 3.run build打包(报错)
    在这里插入图片描述

  • 4.https://v4.webpack.docschina.org/loaders/,配置cssloader文档

  • 5.npm install --save-dev css-loader@2.0.2

  • 6.npm install style-loader@0.23.1 --save-dev

  • 7.配置webpack.json.js文件
    在这里插入图片描述

  • 8.index.html的使用

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
    </head>
    <body>
        你好
     <h2>
         你好
     </h2>
    <script src="dist/bundle.js"></script>
    </body>
    </html>
    

5.2 less的loader使用(同理)

  • 1.创建less文件
    在这里插入图片描述

    @fontSize: 50px;
    @fontColor: orange;
    
    body{
        font-size: @fontSize;
        color: @fontColor;
    }
    
  • 2.引入less文件(main.js)

    //1.使用commonjs的模块化规范
    const {add,mul} = require('./js/mathUtils.js');
    
    console.log(add(20,30));
    console.log(mul(20,30));
    
    //2.使用ES6的模块化规范
    import {name,height} from './js/info.js';
    console.log(name);
    console.log(height);
    
    
    //3.依赖css文件
    require("./css/normal.css")
    
    //4.依赖less文件
    require("./css/special.less")
    
  • 3.npm install less-loader@4.1.0 --save-devnpm install less@3.9.0 --save-dev

  • 4.配置webpack.json.js文件
    在这里插入图片描述

  • 5.打包 run build

5.3 图片文件处理

  • 1.创建img文件
    在这里插入图片描述

  • 2.修改css文件

    body {
        /* background-color:red; */
        background-image: url("../img/timg.jpg");
    }
    
  • 3.直接打包会出错,需要安装url-loader包 npm install url-loader@1.1.2 --save-dev

  • 4.修改webpack.json.js文件
    在这里插入图片描述

  • 5.这时候打包会成功,但是换了一张的图片就会报错
    在这里插入图片描述

  • 6、安装file-loader处理大文件npm install file-loader@3.0.1 --save-dev

  • 7、再次打包即可成功
    在这里插入图片描述
    注:可以发现,对于大的图片打包成功会输出到dist文件夹下,此时引用的话会找不到,需要配置下路径

  • 8.修改webpack.config.js
    在这里插入图片描述

  • 9.另外对于生成的图片名字太长,我们可以配置下生成规则–webpack.config.js,表示生成名字+8位哈希值+扩展名
    在这里插入图片描述

5.4 babel的使用(es6转es5)

  • 1.npm install --save-dev babel-loader@7 babel-core babel-preset-es2015
  • 2.配置webpack.json.js文件
    在这里插入图片描述
  • run build

6.webpack中配置Vue

6.1 引入vue.js

  • 1 . npm install vue@2.5.21 --save 因为我们后续是在实际项目中也会使用vue的,所以并不是开发时依赖

  • 2 . main.js引入

    //1.使用commonjs的模块化规范
    const {add,mul} = require('./js/mathUtils.js');
    
    console.log(add(20,30));
    console.log(mul(20,30));
    
    //2.使用ES6的模块化规范
    import {name,height} from './js/info.js';
    console.log(name);
    console.log(height);
    
    
    //3.依赖css文件
    require("./css/normal.css")
    
    //4.依赖less文件
    require("./css/special.less")
    
    //5.使用Vue进行开发
    import Vue from "vue"
    new Vue({
        el:'#app',
        data:{
            name : 'codewhy'
        }
    })
    
  • 3.run build(报错)—这个错误说的是我们使用的是runtime-only版本的Vue,

    在这里插入图片描述

  • 4.修改webpack.config.js配置,即可成功
    在这里插入图片描述

  • 5.index.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
    </head>
    <body >
        <div id="app">
            你好
        </div>
    
     <h2>
         你好
     </h2>
    <script src="dist/bundle.js"></script>
    </body>
    </html>
    

6.2 el和template的区别

  • 正常运行之后,我们来考虑另外一个问题:

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

    • 在前面的Vue实例中,我们定义了el属性,用于和index.html中的#app进行绑定,让Vue实例之后可以管理它其中的内容
    • 这里,我们可以将div元素中的{{message}}内容删掉,只保留一个基本的id为div的元素
    • 但是如果我依然希望在其中显示{{message}}的内容,应该怎么处理呢?
    • 我们可以再定义一个template属性,代码如下:
      在这里插入图片描述
  • 那么,el和template模板的关系是什么呢?

    • 在我们之前的学习中,我们知道el用于指定Vue要管理的DOM,可以帮助解析其中的指令、事件监听等等。
    • 而如果Vue实例中同时指定了template,那么template模板的内容会替换掉挂载的对应el的模板。
  • 这样做有什么好处呢?

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

6.3 分离template模板

  • 书写template模块非常麻烦怎么办呢?

    • 没有关系,稍后我们会将template模板中的内容进行抽离。
    • 会分成三部分书写:template、script、style,结构变得非常清晰。
      在这里插入图片描述
  • 1 .App.vue文件

     <template>
        <div>
            <h2 class="title">{{message}}</h2>
            <button @click="btnClick">按钮</button>
            <h2>{{name}}</h2>
            <Cpn/>
        </div>
    </template>
    
    
    <script>
    import Cpn from "./Cpn.vue"
    export default {
        name:"App",
        components: {
          Cpn  
        },
         data(){
            return {
                name : 'codewhy',
                message:"123"
            }
        },
        methods:{
            btnClick(){
    
            }
        }
    }
    </script>
    
    <style scoped>
        .title{
            color:green;
        }
    </style>
    
  • 2 .子组件Cpn.vue文件

     <template>
        <div>
            <h2 class="title">我是cpn组件的标题</h2>
            <p>我是cpn组件的内容</p>
            <h2>{{name}}</h2>
        </div>
    </template>
    
    
    <script>
    export default {
        name:"Cpn",
         data(){
            return {
                name : 'Cpn的组件的name',
            }
        },
        methods:{
            btnClick(){
    
            }
        }
    }
    </script>
    
    <style scoped>
        .title{
            color:green;
        }
    </style>
    
  • 3 .main.js引入App.vue

    //1.使用commonjs的模块化规范
    const {add,mul} = require('./js/mathUtils.js');
    
    console.log(add(20,30));
    console.log(mul(20,30));
    
    //2.使用ES6的模块化规范
    import {name,height} from './js/info.js';
    console.log(name);
    console.log(height);
    
    
    //3.依赖css文件
    require("./css/normal.css")
    
    //4.依赖less文件
    require("./css/special.less")
    
    //5.使用Vue进行开发
    import Vue from "vue"
    // import App from "./vue/app"
    import App from './vue/App.vue'
    
    const  app = new Vue({
        el:'#app',
        // 如果同时有el和template,会直接用template 替换掉el内容
        template:`
            <App/>
        `,
        components:{
            App
        }
    })
    
  • 4 .index.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
    </head>
    <body >
        <div id="app">
            你好
        </div>
    
     <h2>
         你好
     </h2>
    <script src="dist/bundle.js"></script>
    </body>
    </html>
    

7.认识plugin

7.1 添加版权声明

  • 在webpack.config.js配置如下
    在这里插入图片描述
  • 重新打包
    在这里插入图片描述

7.2 HtmlWebpackPlugin

  • 目的:将index.html打包到dist中

  • 1.安装插件npm install html-webpack-plugin@3.2.0 --sava-dev

  • 2.在webpack.config.js导入
    在这里插入图片描述

  • 3.因为index.html的js 打包后会自动引入,所以注释了dist 以及下面的内容

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
    </head>
    <body >
        <div id="app">
            你好
        </div>
    <!-- <script src="dist/bundle.js"></script> -->
    </body>
    </html>
    
  • 4.最后生成的如下
    在这里插入图片描述

7.3 压缩js的插件

  • 1.npm install uglifyjs-webpack-plugin@1.1.1 --save-dev
  • 2.配置webpack.config.js
    在这里插入图片描述
  • 3.npm run build
    • 对js丑化
      在这里插入图片描述

8.plugin的使用搭建本地服务器🚲

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

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

    • npm install --save-dev webpack-dev-server@2.9.1
  • 修改webpack.config.js

    • devserver也是作为webpack中的一个选项,选项本身可以设置如下属性:
    • contentBase:为哪一个文件夹提供本地服务,默认是根文件夹,我们这里要填写./dist
    • port:端口号
    • inline:页面实时刷新
    • historyApiFallback:在SPA页面中,依赖HTML5的history模式

    在这里插入图片描述

  • 修改package.json文件
    在这里插入图片描述

  • 开始热部署npm run dev
    在这里插入图片描述
    这样就会实现,当文件改变的时候,页面会自动修改,因为此时这些修改保存到了内存中,类似于java的热部署

  • 补充1:(自动打开链接)
    在这里插入图片描述

  • 补充2:js压缩在开发中,不应该使用
    在这里插入图片描述

9.webpack的配置分离🚊

  • 目的:开发时,使用一个配置文件;发布时使用另一个配置文件

  • npm install webpack-merge@4.1.5 --save-dev 安装merge包,用于合并下面的配置文件

  • 所以将webpack.config.js抽离成3个文件

  • 1 . 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'), //动态获取绝对路径,__dirname是node中全局变量
            filename :  "bundle.js",
            //publicPath: 'dist/'
        },
        plugins:[
          new webpack.BannerPlugin('最终版权swz所有!'),
          new HtmlWebpackPlugin({
            template:'index.html'
          }),
          //new uglifyjsWebpackPlugin()
        ],
        module: {
            rules: [
                { 
                    test: /\.css$/,
                    // style-loader 将模块的导出作为样式添加到 DOM 中
                    // css-loader 解析 CSS 文件后,使用 import 加载,并且返回 CSS 代码
                    //使用多个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|jpeg|gif)$/i,
                    use: [
                      {
                        loader: 'url-loader',
                        options: {
                            //当加载的图片,小于limit时,会将图片编译成base64字符串形式
                            //反之,需要使用file-loader没模块进行加载
                          limit: 13000,
                          //[]表示变量
                         name: 'img/[name].[hash:8].[ext]'
                        }
                      }
                    ]
                },
                {
                    test: /\.m?js$/,
                    //exclude 排除,include包含
                    exclude: /(node_modules|bower_components)/,
                    use: {
                      loader: 'babel-loader',
                      options: {
                        presets: ['es2015']
                      }
                    }
                  },
                  {
                    test: /\.vue$/,
                    use: ['vue-loader']
                  }
            ]
        },
        resolve:{
          alias: {
            'vue$':"vue/dist/vue.esm.js"
          }
        }
    }
    
  • 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:[
          new uglifyjsWebpackPlugin()
        ]
    })
    
  • 3 . dev.config.js

    const webpackMerge = require('webpack-merge')
    const baseConfig = require('./base.config')
    module.exports = webpackMerge(baseConfig, {
        devServer:{
          contentBase: "./dist",
          inline: true
        }
    })
    
  • 修改配置文件package.json
    在这里插入图片描述
    注:以上安装的模块的版本要对应!!!

学习视频:
https://www.bilibili.com/video/BV15741177Eh?p=90&spm_id_from=pageDriver

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。