0
点赞
收藏
分享

微信扫一扫

​Webpack 入门教程

犹大之窗 2022-04-19 阅读 75
vuewebpack

Webpack 入门教程

webpack的简介和安装

为什么使用webpack

  • 模块化打包:webpack可以帮我们把CommonJS和ES6语法模块化,转化为浏览器可以解释执行的语法。,我们既可以使用到模块化方案带飞我们的好处:避免代码变量命名等冲突,结构清晰,方便复用与管理,也可以通过webpack来满足浏览器的兼容!webpack可以帮我们解析模块间的依赖关系,并正确打包!

  • 兼容更多的前端技术:前端技术和新的规范层出不穷

    上面这是实际还是js和css,但是加入了一些增强语法,他们都可以提高前端开发效率和开发体验!但是这些语法都没有办法直接被浏览器执行,这就需要我们使用webpack,将这些代码进行编译,编写成浏览器可以执行的代码。

  • js规范:ES6、ES7、ES8

  • css预处理器:LESS、SASS

  • 前端框架:vue、react、Angular

  • JS语言改进:CoffeScript和TypeScript

  • 更多功能:webpack可以帮我们管理小素材图标、雪碧图等前端需求细节

webpack的安装

在安装 Webpack 前,你本地环境需要支持 node.js。nodejs自带包管理工具npm.

NodeJS、webpack、npm、vue的关系

  • vue是学习js语言的新框架,新的框架有一部分不被浏览器兼容,如.vue文件,因此我们就需要webpack来帮我们做编译,将编译后的代码变为浏览器可执行的代码

  • npm工具可以帮我们管理各种js类库,打包工具webpack本身就是一个js的类库,因此需要使用npm帮助我们管理

  • webpack是一个js类库,不仅可以帮助我们编译,还可以帮助我们打包静态资源。

检查NodeJS版本

NodeJS安装完成以后,我们可以查看安装的版本,最其要求8.10+

node -v

安装webpack

全局安装webpack

npm install webpack -g

局部安装

npm install webpack  --save-dev

  • 局部安装和全局安装的区别:全局安装对所有版本生效,局部安装只对当前项目生效

  • 局部版本的优先级高于全局安装版本

  • –save-dev表示该类库只在编译期间使用,打包结果中不包含该类库。webpack只是在开发阶段使用,浏览器运行期间不需要这部分代码。

webpack使用

项目初始化

使用npm init ,初始化前端项目

局部安装webpack

npm install webpack@3.6.0 --save-dev

webpack安装完成后,我们发现在package.json文件中自动生成了一段配置代码。这段配置代码表示该项目使用webpack进行模块化静态资源打包,并且只在开发期间使用

项目创建

使用npm init初始化项目以后,创建文件和目录如下

  • dist目录,手动创建,用于存放打包结果

  • src目录,手动创建,用于存放被打包的资源文件js、css、image等

  • index.html,手动创建,项目首页

  • node-modules目录,这个目录是自动生成的不需要手动新建,npm包管理工具引入的包都在这个目录下存放

furit.js代码

let apple ="苹果"
let watermelon="西瓜"
let pear= "梨"

module.exports ={
    apple,
    watermelon,
    pear
}

main.js代码

let {apple,watermelon,pear} =require('./js/furit')

document.writeln(apple);
document.writeln(watermelon);
document.writeln(pear);

index.html代码

<html>
    <head>
        <meta charset="utf-8">
    </head>
    <body>
        <script type="text/javascript" src="./dist/bundle.js" charset="utf-8"></script>
    </body>
</html>

使用webpack打包js模块

D:\software\file\typora\vue\webpack-demo\node_modules\.bin\webpack src/main.js dist/bundle.js

访问index.html结果如下

通过npm run build打包命令讲解webpack基础配置

创建webpack.config.js作为wabpack的配置文件

const path = require('path')

module.exports = {
    entry: "./src/main.js",
    output: {
        path: path.resolve(__dirname,'dist'),
        filename: "bundle.js"
    }
};

  • 引入NodeJS提供的模块path

  • path.resolve方法作用是完成路径拼接,__dirname是全局变量,代表当前文件所在路径

  • __dirname + ‘dist’ 就是bundle.js出口文件的完整的绝对路径

  • entry: 入口文件

  • output.filename:表示出口文件路径和文件名

使用如下命令打包

D:\software\file\typora\vue\webpack-demo\node_modules\.bin\webpack

也就是说,我们不用再使用命令行参数了,我们把入口、出口文件参数写在了配置文件里面。离我们使用npm run build命令来实现打包操作还差一步,在项目配置管理文件package.json里面加入如下一行代码:

加入这一行代码的意义在于:当我们输入npm run build命令的时候,会自动查找package.json文件script.build脚本,从而执行webpack命令。并且这个webpack命令不是全局的,默认就是node_modules/.bin下面局部安装的webpack版本,所以我们就不用再加上前缀路径。至此,我们就可以使用npm run build命令来实现项目模块化资源文件打包,和vue-cli脚手架实现的原理一致。如下:

npm run build

css文件处理打包

在src文件夹下,创建css文件夹,在css文件夹中创建一个style.css文件,文件内容是,设置背景为黄色

body {
    background: yellow;
}

在main.js中将style.css当作一个模块引入

require("!style-loader!css-loader!./css/style.css")

在webpack.config.js配置css

const path = require('path')

module.exports = {
    entry: "./src/main.js",
    output: {
        path: path.resolve(__dirname,'dist'),
        filename: "bundle.js"
    },
    module: {
        loaders: [
            { test: /\.css$/, loader: "style-loader!css-loader" }
        ]
    }
};

这时,我们调用npm run build打包,就会出现如下错误:需要合适的loader去处理css文件类型

将npm镜像设置为阿里源镜像

npm config set registry http://registry.npmmirror.com

所以,我们安装css-loader。实际上是安装css-loader和style-loader。css-loader帮助我们加载css文件,style-loader帮我们把样式嵌入到文档中

npm install --save-dev   css-loader@0.28.3  style-loader0.18.1

注不同版本的webpack对应的css-loader和style-loader版本不同,可以在

https://github.com/webpack/webpack/blob/webpack版本/package.json中查找对应版本。

再次运行项目

npm run build

结果如下

CSS中图片文件处理

在src文件夹中创建image文件夹,放入两种图片2.jpg1.png大于10kb,修改style.css文件

body {
    background-color:yellow;
    background: url(../image/1.png);

    font-size:20px;
    color: yellow;
}

div{
    height: 100px;
    width: 100px;
  

}

  • 修改main.js,新添加一个jpg
import less10kb from './image/2.jpg';
require("./css/style.css");
let {apple,watermelon,pear} =require('./js/furit')
document.writeln(apple);
document.writeln(watermelon);
document.writeln(pear);
function component() {
    const element = document.createElement('div');
   // 将图像添加到我们已经存在的 div 中。
   const myIcon = new Image();
   myIcon.src = less10kb;
   myIcon.style="width: 400px; height: 200px;";
   element.appendChild(myIcon);
    return element;
  }
 
  document.body.appendChild(component());

  • 安装处理图片的url-loader,file-loader,使用如下命令:
npm install --save-dev@  url-loader@4.1.1  file-loader@file-loader

  • 然后配置webpack.config.js,添加对css中图片的处理策略:
const path = require('path')
module.exports = {
    entry: './src/main.js',
    output:{
      path: path.resolve(__dirname,'dist'),
      filename: 'bundle.js',
      publicPath:"dist/"
    },
    module: {
        rules: [
            { 
                test: /\.css$/, 
                use:[ "style-loader", "css-loader"]
             },
             {
                test: /\.(png|jpg|gif|jpeg)$/,
                use:[
                    {
                      loader : 'url-loader',
                      options:{
                        limit: 10240,
                        name: 'img/[name].[hash:8].[ext]'
                      }
                    }
                  ]
             }
        ]
    }
}

  • test配置用于匹配处理图片的文件后缀名

  • use.options.limit:10240表示如果图片文件小于10kb,就把它打包到结果文件bundle.js

  • publicPath:"dist/"表示可以被公开访问的独立资源文件存放的目录

  • file-loader:假如图片小于10kb,我们就把图片转换为Base64编码打包到bundle.js文件中。那么,如果图片比较大,打包到js文件会比较臃肿,使用file-loader将图片文件独立于js文件存在并可以被使用

再次运行

npm run build

  • use.options.name:自定义图片名称

  • img:文件要打包到目标文件夹

  • name:图片原始文件名

  • hash:8:8位的hash值,保证一定的随机性

  • ext:使用图片原来的扩展名

js规范兼容babel

什么是ECMAScript

ECMAScript,简称ES,是由Ecma国际(前身为欧洲计算机制造商协会,英文名称是European Computer Manufacturers Association)按照ECMA-262和ISO/IEC 16262标准制定的一种脚本语言规范。javascript是ECMAScript规范的实现,ECMAScript是javascript的标准。那么都有哪些常用的标准呢?

大名小名备注
ECMAScript 5ES5兼容绝大部分浏览器
ECMAScript 2015ES6兼容绝大部分现代浏览器
ECMAScript 2016ES7浏览器兼容性一般
ECMAScript 2017ES8浏览器兼容性一般

ES5是我们目前前端js语言届的“普通话”,也就是说ES5可以被大部分浏览器兼容。但是ES5面向开发人员不够友好,语法繁琐并且难于理解,特别是原型、对象、集成;也没有一些新的js特性,如:Promise等的支持。

babel是什么

Babel 是一个javascript编译器,主要用于将 ECMAScript 2015+ 版本的代码转换为向后兼容的 JavaScript 语法,以便能够运行在当前和旧版本的浏览器或其他环境中。中文网站地址:https://www.babeljs.cn/

注意看下面的这个动图,左侧是转换钱的ES6+语法,右侧为转换之后ES5的语法

babel-loader

css打包转换我们使用css-loader,图片打包转码我们使用url-loader。我们将ES6+的语法转换为“普通话”ES5使用的是babel-loader。我们首先来安装它:

npm install --save-dev babel-loader@7.1.5 babel-core@6.26.3 babel-preset-env@1.7.0

可以看到除了 babel-loader,我们还安装了 babel-core,因为前者对后者有依赖关系。babel-preset用于识别语法规范,babel-preset有多项选择安装,比如es2015,es2016,es2017,env。但是一般用的比较多的是babel-preset-env,env表示兼容ES2015+的语法。配置webpack.config.js中的module.rules代码段:

             {
                test: /\.js$/,
                exclude: /(node_modules)/,
                use:{
                  loader: 'babel-loader',
                  options:{
                      presets:[
                          [
                              'env',
                              {
                                  targets:{
                                      browsers:['>1%', 'last 2 version' ,'not ie <=8']
                                  }
                              }
                          ]
                      ]
                  }
                }
              },

  • test中正则表达式表示只针对js文件做处理

  • exclude表示不对node_modules目录下的文件做处理,这下面js文件不是我们写的

  • 使用env设置:表示兼容ES2015+的语法

  • targets.browers表示兼容使用率大于1%,并且兼容浏览器最新2个版本,并且不兼容IE8及以下浏览器

然后我们使用npm run build打包,打包之后结果如下。我们原始代码中定义变量使用的是let关键字,被转换为ES5规范的变量定义关键字var。

webpack整合vue

npm install vue --save

我们来写一个简单的例子来使用Vue,首先在main,js中使用Vue:

import Vue from 'vue'
new Vue({
    el:'#app',
    data:{
        message:"springboot葵花宝典"
    }
})

然后在index.html中,建一个id#app的div,使用插值表达式引用message变量

<html>
    <head>
        <meta charset="utf-8">
    </head>
    <body>
        <div id = 'app'>
            {{message}}
        </div> 
    </body>
    <script type="text/javascript" src="./dist/bundle.js" charset="utf-8"></script>
</html>

webpack.config.js中添加resolve

    resolve: {
        alias: {
            'vue$': 'vue/dist/vue.esm.js'
        }
      },

:resolve和module同级

页面访问

npm run build

vue单文件组件

在src文件夹下创建vue文件夹,然后创建test.vue

<template>
  <div>
     <input type="text" v-model="message">
    <h2 style="color:blak">输入的内容是:{{message}}</h2></div>
</template>

<script>
export default {
  name: 'test',
  data(){
    return {
      message: 'springboot葵花宝典'
    }
  }
}

</script>
<style scoped>
</style>

  • template标签里面书写html视图层代码

  • script标签里面写模块化的Vuejs代码

  • style标签里面写针对该组件的视图样式

这种写法降低了视图、数据、样式之间的耦合度,对开发者更加友好。然后,我们可以在项目入口文件main,js这样使用该组件

import Vue from 'vue'
import test from './vue/test.vue'
new Vue({
    // el:'#app',
    // data:{
    //     message:"springboot葵花宝典"
    // }
    render: h=> h(test)
}).$mount("#app")

安装需要vue-loader等组件

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

在webpack.config.js中加入如下配置

              {
                test: /\.vue$/,
                use:['vue-loader']
              }

运行程序结果如下

什么是webpack插件

我们通常意义上,所说的软件应用的插件就是指对原有类库或者软件功能进行扩展,通常需要额外安装的类库或软件。所以从广义上讲css-loader、url-loader等都是webpack的插件。但是,我们一般不把它们叫做webpack的插件,而是称它们为转换器、加载器或者直接叫loader。还有一些对webpack功能进行扩展的类库或者程序,比如:htmlWebPackPlugin、uglifyJsPlugin,它们都对webpack的功能进行了扩展。而且不是完成转换加载之类的功能扩展,我们把这部分软件扩展程序,称为:webpack的插件

htmlWebPackPlugin

我们之前通过浏览器访问的index.html是存放在项目根目录下面,而不是存放在dist目录下面。还有需要明白一点:dist目录下的文件才是我们真正做生产环境发布的程序文件。所以说,我们需要将index.html打包到dist文件夹里面。htmlWebPackPlugin帮我们做两件事:

  • 帮我们把index.html(html模板)打包到dist文件夹下面

  • 将最终的打包结果bundle.js,以script标签形式帮我们引入到html里面

所以,我们需要先把index,html里面手动引入的bundle.js代码删掉。从此以后就不需要手动引入bundle.js了。htmlWebPackPlugin会帮我们引入。

安装HtmlWebpackPlugin插件

npm install html-webpack-plugin@3.2.0 --save-dev

安装完成之后,在webpack.config.js里面做如下的配置:

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

注:plugin和module同级

上面代码含义是使用和webpack.config.js同一目录下的index.html作为模板生成项目的访问入口。此外,我们之前为了正确的访问在css代码里面的图片文件,我们加上了publicPath的配置。我们将html打包到dist文件夹之后,这个配置就不需要了,删掉!

    output:{
      path: path.resolve(__dirname,'dist'),
      filename: 'bundle.js',
      //publicPath:"dist/"
    },

npm run build


后查看dist文件

![](https://mmbiz.qpic.cn/mmbiz_png/fx1lx9ichONZv2csslB4MGk3dySYnXL4jqvjucFfCeVXXrfDwyXbsATBE60vJs1Goiay2xFYV1aGd1NpYEf6PeibA/640?wx_fmt=png)

#### uglifyJsPlugin  

生产环境中,我们通常会对js文件压缩,丑化。去掉空格、换行,变量替换为简单的字符。这样做有2点好处:

*   让代码更难以理解,黑客很难读懂压缩丑化之后的代码,从而一定程度上防止可以针对性的攻击。(但实际上对于有经验的web渗透人员,这个也起不到太大的效果,只能做到防君子不防小人)
    
*   压缩之后的代码体积更小,更有利于网络请求的性能优化
    

我们使用uglifyJsPlugin来完成对js文件压缩,丑化。首先安装:

npm install uglifyjs-webpack-plugin@1.1.1  --save-dev


我们安装1.1.1版本,与Vue-CLI2一致,避免兼容性问题!安装完成之后,在webpack.config.js里面做如下的配置:

const uglifyJsPlugIn = require(‘uglifyjs-webpack-plugin’)

      plugins:[
        new htmlWebpackPlugin({
          template: 'index.html'
        }),
        new  uglifyJsPlugIn() 
      ],

```

#### 本地调试服务webpack-dev-server

我们在写代码的时候,希望我们改完代码之后,能够让浏览器自动感知到我们对代码的改动,也就是热部署,方便我们做代码的调试。在vue-cli脚手架中是使用npm run dev命令来实现的。现在我们就来实现这个功能。首先,要明确的说,这个热部署调试功能是webpack为我们实现的,webpack提供了一个本地开发服务器,依赖于NodeJS,内部使用express框架。它是一个单独的模块,我们先来安装它,在项目根目录执行命令:

```
npm install --save-dev webpack-dev-server@2.9.1

```

在webpack.config.js文件里面module.exports代码段下加入如下配置:

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

```

*   contentBase:静态资源访问服务的根路径
    
*   port:服务端口号
    
*   inline:发生改变,实时热部署刷新浏览器页面
    

然后在package.json项目配置文件里面,加入如下配置:

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

```

\--open表示,本地服务启动,自动打开浏览器,访问contentBase下面的index.html

使用`npm run dev`运行程序

![](https://img-blog.csdnimg.cn/img_convert/b56c77bb478646e85023e5c8a09e2afb.png)

### 环境配置分离  

首先,我们回顾上一节中给大家介绍的内容:

*   uglifyJsPlugin插件,用于对打包代码进行压缩,丑化。从而减少代码体积,提高网络传输效率。
    
*   webpack-dev-server用于本地代码开发的时候,进行代码调试。实时的热部署更新。
    

大家可以看到,虽然上面两个都是webpack配置项目,但是我们通常希望uglifyJsPlugin只对生产环境的代码进行丑化,压缩。在我们平时开发过程中,我们还是希望代码是具有可读性、规范化的。而webpack-dev-server相反,我们希望实时热部署更新只在开发阶段生效,他并不需要在生产环境中生效。也就是说,配置项分为三种:

*   期望对生产环境和测试环境都生效的配置(如下图红色框和黄色框之外的配置)
    
*   期望只对测试环境生效的配置(黄色框的配置:本地调试服务设置)
    
*   期望只对生产环境生效的配置(红色框的配置:代码压缩丑化插件)
    

#### 建立基本文件结构

*   webpack.base.conf.js:webpack基础配置,应该包含第二小节图中的红色框和黄色框之外的所有配置
    
*   webpack.dev.conf.js:测试环境生效配置,应该包含第二小节图中的黄色框的配置
    
*   webpack.prod.conf.js:测试环境生效配置,应该包含第二小节图中的红色框的配置
    

webpack.config.js(红色框)在以上三个文件配置完成之后,删除。

![](https://img-blog.csdnimg.cn/img_convert/425823c93bbff6ede0ff7fa138ecaa54.png)

#### webpack-merge  

通过前两个小节的说明,我相信大家能够明白,实际上:生产环境的完成配置 = base配置 + prod配置 测试环境的完整配置 = base配置 + dev配置

那么,现在我们就要一个问题,如何完成“+”加这个动作。也就是如何完成配置合并,我们需要使用到webpack-merge,先来安装它:

```
npm install webpack-merge@4.2.2

```

第一步:将webpack.config.js代码copy到webpack.base.conf.js,然后删除第二小节红色框和黄色框的部分。也就是去除生产环境和测试环境的个性化配置。

```
    entry: './src/main.js',
    output:{
      path: path.resolve(__dirname,'../dist'),
      filename: 'bundle.js',
    },

```

第二步:调整webpack打包输出文件路径的配置,原来是dist换成'../dist',因为打包配置文件都放在了build目录下,它的上一级目录下的dist目录是文件打包输出路径。

第三步:在webpack.dev.conf.js中使用webpack-merge进行配置合并,同理需要将contentBase的dist换成‘../dist’,代码如下:

```
const path = require('path')
const merge = require('webpack-merge')
const baseConfig = require('./webpack.base.conf')

module.exports = merge(baseConfig,{
  devServer:{
    contentBase: path.resolve(__dirname,'../dist'),
    inline: true,
    port: 8888
  }
});


```

第四步:需要调整package.json的`npm run dev`启动脚本,显式的指定配置文件的所在位置。否则,webpack还会默认使用根目录下面的webpack.config.js作为配置文件。

```
  "scripts": {
    "build": "webpack --config ./build/webpack.prod.conf.js",
    "test": "webpack --config ./build/webpack.dev.conf.js",
    "dev": "webpack-dev-server --open --config ./build/webpack.dev.conf.js"
    
  },

```

至此,我们测试环境的配置文件就完成了!我相信大家可以按照测试环境的配置文件拆分方式,和代码配置webpack-merge,把生产环境的配置独立完成!

如果您觉得本文不错,欢迎关注,点赞,收藏支持,您的关注是我坚持的动力!  

原创不易,转载请注明出处,感谢支持!如果本文对您有用,欢迎转发分享!
举报

相关推荐

0 条评论