首页 > Web开发 > 详细

手写webpack配置文件

时间:2020-02-18 22:40:11      阅读:63      评论:0      收藏:0      [点我收藏+]

webpack是一款模块加载器兼打包工具,它能把各种资源,例如JS(含JSX)、coffee、样式(含less/sass)、图片等都作为模块来使用和处理,它能有Grunt或Gulp所有基本功能。

Webpack 之前...
  1. 文件关系错综复杂
  2. 模块话支持不友好
  3. 市面上的一些自动化构建工具只能配合各种插件做js,css等压缩,可以替代手动实现自动化工作
  4. 静态资源请求效率比较低
  5. 浏览器对高级js特性兼容性不够好
    ...
Webpack 出现...

技术分享图片

我们看下webpack官方文档给出的图,看上去就很高级对不对,看看他有啥好用的地方

  1. 将依赖的模块分片化,并且按需加载
  2. 解决大型项目初始化加载慢的问题
  3. 每一个静态文件都可以看成一个模块
  4. 可以整合第三方库
  5. 能够在大型项目中运用
  6. 可以自定义切割模块的方式
    ...

反正就是十分厉害??,我也不叨叨叨继续吹了,开始学习webpack吧

开始学习webpack

安装node环境

自行在node官网,选择合适电脑的版本进行下载,并安装,通过node -v检查是否安装成功

在项目中安装和配置webpack

npm install webpack webpack-cli --save

在项目的根目录中,运行上述命令,安装webpack脚手架

在项目的根目录中新建webpack的配置文件 webpack.config.js,并且初始化配置文件

module.exports = {
    mode:'development'  //选择模式,是开发模式,还是生产模式(production)
}

修改package.json文件

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

创建项目

  1. 创建文件夹,我这文件夹的名字叫demoWebpack,创建完之后在编辑器中打开,我这用的是VSCode,点击Terminal中new terminal,在TERMINAL中输入npm init -y,文件夹中就会多一个package.json文件

  2. 在项目中新建src文件夹,之后的源代码都会放在这

  3. src文件夹中,新建一个index.html作为首页,然后创建其他的css,js文件

  4. 再项目根目录下再创建image文件夹,用来存放图片

最后的项目结构是这个样子的

技术分享图片

index.html(为了检验写的css和js都正确,所以我这先把他引入,看了下效果)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <link rel="stylesheet" href="style.css">
</head>

<body>
    <div>
        <div class="box1"></div>
        <img src="../image/1.jpeg" alt="" srcset="">
    </div>
    <script src="./index.js"></script>
</body>
</html>

index.js

(function(){
    let arr = [1,2,3,4,5];
    arr.forEach((item) => {
        console.log(item)
    })
})();
document.getElementsByTagName('div')[1].addEventListener('click', function () {
    console.log(this)
    this.className = 'box2'
})

style.css

.box1{
    width: 100px;
    height: 100px;
    background-color: yellowgreen;
}
.box2{
    transition: 2s;
    transform:translateX(300px) ;
    width: 100px;
    height: 100px;
    background-color: teal;
    border-radius: 50%;
}

运行npm run dev,就会发现多出来个dist文件夹,里面有个main.js,这是我们就写了mode出来的文件
修改index.html引入js的代码

<script src="../dist/bundle.js"></script>

配置打包的出入口

webpack4.x版本中默认入口文件是src文件下的index.js,打包出口dist 文件夹下的 main.js,如果需要修改出入口,可以再webpack.config.js内进行修改

const Path = require('path')

module.exports = {
    mode:'development',  //选择模式,是开发模式,还是生产模式(produce)
    entry: Path.join(__dirname, './src/index.js'),//打包文件入口路径
    output: {
        path: Path.join(__dirname, './dist'),//输出文件存放路径
        filename: 'bundle.js'//输出文件名称
    },
}

配置webpack的自动打包功能

npm install webpack-dev-server --save
运行上述命令行安装支持项目自动打包的工具,修改package.json中的配置

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

修改index.html引入js,css的代码(项目的src文件夹下,会有一个看不见的bundle.js文件)

<link rel="stylesheet" href="../src/style.css">
<script src="/bundle.js"></script>

重新运行 npm run dev,打开 http://localhost:8080 你会看到整个项目的文件夹都显示在页面上了

技术分享图片

进入src中的index.html页面,修改js文件,项目就会自动打包,都不需要刷新浏览器,自动就会出现最新效果

生成预览页面

打开 http://localhost:8080/ 还需要点开src文件夹,着实鸡肋,最好我们打开http://localhost:8080/就能出现页面,那我们操作吧
npm install html-webpack-plugin --save
安装生成预览页面的插件,修改webpack.config.js文件

const HtmlWebpackPlugin = require('html-webpack-plugin')//插件用于生成预览页面
const htmlPlugin = new HtmlWebpackPlugin({
    template: './src/index.html',//指定要用到的模板文件
    filename: 'index.html' //指定生成的文件的名称,该文件存在于内存中,在目录中显示
})
module.exports = {
    plugins: [htmlPlugin], //plugins数组是webpack打包期间会用到的一些插件列表
}

运行npm run dev,打开 http://localhost:8080 就会直接看到页面,如果想要运行之后在浏览器直接打开http://localhost:8080,需要配置一下package.json文件

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

--open 表示打包完自动打开浏览器页面

如果你还想指定ip地址和端口打开的话,就需要再配置中新增host和port,例如"dev": "webpack-dev-server --open --host 127.0.0.1 --port 8081",这就会打开http://127.0.0.1:8081/这个页面

webpack中的加载器

webpack默认只能打包.js结尾的文件,非.js结尾的模块webpack打包不了,需要调用相应的loader加载器才可以正常打包,我们看下loader打包的过程
技术分享图片

打包处理css文件

我们现在不用页面引入css的方式来载入css样式,我们将css文件在index.js中import进去,保存后,你会发现,控制台立即就飘红了
技术分享图片

大概的意思就是,没有css的加载器,所以现在我们要安装css的loader

npm install style-loader css-loader --save

安装完成后,在webpack.config.js文件中,配置相应的规则

module: {//所有第三方文件模块匹配规则
     rules: [
        {
            test: /\.css$/, 
            use: ['style-loader', 'css-loader']    //test表示匹配的文件类型,use表示需要调用的loader
        }
    ]
}

修改index.js

import "./style.css"

npm run dev,运行,之前的报错已经消失了,页面也出现了
打包处理less/sass文件也是类似的过程,我这就写一下less吧

  1. 首先还是要安装对应加载器 npm install less-loader less --save
  2. webpack.config.js添加相应的规则
module: {//所有第三方文件模块匹配规则
     rules: [
        {
            test: /\.less$/, 
            use: ['style-loader', 'css-loader','less-loader']    //test表示匹配的文件类型,use表示需要调用的loader
        }
    ]
}

all.less

body{
    background-color: pink;
    
    img{
        border-radius: 50%;
        width: 500px;
        height: 500px;
    }
}

index.js

import "./all.less";

重新运行,就可以看到all.less中写的样式了,要用sass的话也是一样的步骤哦

配置postCSS自动添加css的兼容前缀

安装对应加载器npm install postcss-loader autoprefixer --save
在根目录下创建postcss的配置文件postcss.config.js

const autoprefixer = require('autoprefixer')    //导入自动添加前缀的插件
module.exports = {
    plugins: [autoprefixer]  //挂载插件
}

修改webpack.config.js

{
    test: /\.css$/, 
    use: ['style-loader', 'css-loader','postcss-loader']    //test表示匹配的文件类型,use表示需要调用的loader
},

重新运行npm run dex,就ok了

打包样式中的图片和字体文件

安装对应loader npm install url-loader file-loader --save

webpack.config.js添加相应的规则

{
    test:/\.jpg|jpeg|png|gif|bmp|ttf|eot|svg|woff|woff2$/,
    use:['url-loader?limit=15000']
},

我们把all.less body的背景颜色改成背景图片

body{
    background:url(../image/1.jpeg);    
}

重新运行npm run dex,ok

打包处理js中的高级语法

本来打算在index.js中写一些js的高级语法,比如说async+promise,class这类的东西,记得之前写的时候,是需要安装babel,不然会报错,但是,我今天试的时候,发现不用babel,竟然也不会报错了,真是神奇,但是为了避免,我这边可能有什么意外,导致不用安装babel就可以成功,所以还是把安装使用babel的步骤写出来,如果你写这种语法报错,可以按照这个教程来解决这个问题

  1. 安装babel转换器相关的包,npm install babel-loader @babel/core @babel/runtime --save
  2. 安装Babel语法插件相关的包,npm install @babel/preset-env @babel/plugin-transform-runtime @babel/plugin-proposal-class-properties --save
  3. 在项目的根目录下,创建babel.config.js
    babel.config.js
module.exports = {
    presets: ['@babel/preset-env'],
    plugins: ['@babel/plugin-transform-runtime', '@babel/plugin-proposal-class-properties']
}

webpack.config.js添加相应的规则

{
    test:/\.js$/,
    use:['babel-loader'],
    exclude:/node_modules/
},

exclude:/node_modules/表示babel-loader不需要处理node_modules文件夹内的js文件

index.js修改如下

import "./style.css";
import "./all.less";

(function(){
    let arr = [1,2,3,4,5];
    arr.forEach((item) => {
        console.log(item)
    })
})();
document.getElementsByTagName('div')[1].addEventListener('click', function () {
    console.log(this)
    this.className = 'box2'
})

function hanleTime(){
    return new Promise((resolve,reject) => {
        setTimeout(() => {
            resolve('我是个异步函数')
        }, 2000);
    })
}
async function asyncUtil(){
    let result = await hanleTime()
    console.log(result)
}

asyncUtil()

class Person {
    //类的构造函数
    constructor(name, age) {
        this.name = name
        this.age = age
    }

    //这个方法相当于构造函数Person2.prototype.showName = function () {}创建出来的方法
    // showName(),供实例对象使用
    showName() {
        console.log(this.name, this.age)
    }

    //这个是Person类自身的方法,实例对象不能使用
    static test() {
        console.log('hahahahhah')
    }
}

let person = new Person('Bob',23)
person.showName()

运行就行了

配置vue组件的加载器

安装 npm install vue-loader vue-template-compiler --save
配置webpack.config.js

const VueLoaderPlugin = require('vue-loader/lib/plugin')
module.exports = {
    ...
    plugins: [new VueLoaderPlugin()]
            {
                test:/\.vue$/,
                loader:'vue-loader'
            }
        ]
    }
}

创建App.vue文件

<template>
  <div>
    <h1>我是vue组件</h1>
  </div>
</template>

<script>
export default {
    name:'App',
    data(){
        return{

        }
    }
}
</script>

<style scoped>

</style>

index.js修改如下

import "./App.vue"

在webpack中使用vue

安装 npm install vue --save
src``文件夹下的index.js```文件中,引入vue,创建 vue 的实例对象,并指定要控制el区域,然后通过render函数渲染App根组件

//导入Vue构造函数
import Vue from "vue" 
//导入App根组件
import App from "./App.vue"

const vm = new Vue({
    //指定vm实例要控制的页面区域
    el:"#app",
    //通过render函数,把指定的组件渲染到el区域中
    render:h => h(App)
})

index.html中添加id为app的盒子

<div id="app"></div>

此时网页中就会出现“我是vue组件”这几个字

webpack 打包

修改package.json

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

运行npm run build就可以打包了

好了,到这所有的步骤就都结束了,附上所有的代码

webpack.config.js

const Path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')//插件用于生成预览页面
const VueLoaderPlugin = require('vue-loader/lib/plugin')
const htmlPlugin = new HtmlWebpackPlugin({
    template: './src/index.html',//指定要用到的模板文件
    filename: 'index.html' //指定生成的文件的名称,该文件存在于内存中,在目录中显示
})

module.exports = {
    mode: 'development',  //选择模式,是开发模式,还是生产模式(produce)
    entry: Path.join(__dirname, './src/index.js'),//打包文件入口路径
    output: {
        path: Path.join(__dirname, './dist'),//输出文件存放路径
        filename: 'bundle.js'//输出文件名称
    },
    plugins: [htmlPlugin,new VueLoaderPlugin()], //plugins数组是webpack打包期间会用到的一些插件列表
    //webpack只能打包.js文件,当需要打包其他非.js文件需要调用loader加载器进行打包
    module: {//所有第三方文件模块匹配规则
        rules: [
            {
                test: /\.css$/, 
                use: ['style-loader', 'css-loader','postcss-loader']    //test表示匹配的文件类型,use表示需要调用的loader
            },
            {
                test: /\.less$/, 
                use: ['style-loader', 'css-loader','less-loader']
            },
            {
                test:/\.jpg|jpeg|png|gif|bmp|ttf|eot|svg|woff|woff2$/,
                use:['url-loader?limit=15000']
            },
            {
                test:/\.js$/,
                use:['babel-loader'],
                exclude:/node_modules/
            },
            {
                test:/\.vue$/,
                loader:'vue-loader'
            }
        ]
    }
}

index.js

import "./style.css";
import "./all.less";


(function(){
    let arr = [1,2,3,4,5];
    arr.forEach((item) => {
        console.log(item)
    })
})();
document.getElementsByTagName('div')[1].addEventListener('click', function () {
    console.log(this)
    this.className = 'box2'
})

function hanleTime(){
    return new Promise((resolve,reject) => {
        setTimeout(() => {
            resolve('我是个异步函数')
        }, 2000);
    })
}
async function asyncUtil(){
    let result = await hanleTime()
    console.log(result)
}

asyncUtil()

class Person {
    //类的构造函数
    constructor(name, age) {
        this.name = name
        this.age = age
    }

    //这个方法相当于构造函数Person2.prototype.showName = function () {}创建出来的方法
    // showName(),供实例对象使用
    showName() {
        console.log(this.name, this.age)
    }

    //这个是Person类自身的方法,实例对象不能使用
    static test() {
        console.log('hahahahhah')
    }
}

let person = new Person('Bob',23)
person.showName()


//导入Vue构造函数
import Vue from "vue" 
//导入App根组件
import App from "./App.vue"

const vm = new Vue({
    //指定vm实例要控制的页面区域
    el:"#app",
    //通过render函数,把指定的组件渲染到el区域中
    render:h => h(App)
})

package.json

{
  "name": "demoWebpack",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "dev": "webpack-dev-server --open --host 127.0.0.1 --port 8081",
    "build":"webpack -p"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "@babel/core": "^7.8.4",
    "@babel/plugin-proposal-class-properties": "^7.8.3",
    "@babel/plugin-transform-runtime": "^7.8.3",
    "@babel/preset-env": "^7.8.4",
    "@babel/runtime": "^7.8.4",
    "autoprefixer": "^9.7.4",
    "babel-loader": "^8.0.6",
    "css-loader": "^3.4.2",
    "file-loader": "^5.0.2",
    "html-webpack-plugin": "^3.2.0",
    "less": "^3.11.1",
    "less-loader": "^5.0.0",
    "postcss-loader": "^3.0.0",
    "style-loader": "^1.1.3",
    "url-loader": "^3.0.0",
    "vue": "^2.6.11",
    "vue-loader": "^15.9.0",
    "vue-template-compiler": "^2.6.11",
    "webpack": "^4.41.6",
    "webpack-cli": "^3.3.11",
    "webpack-dev-server": "^3.10.3"
  }
}

App.vue

<template>
  <div>
     <h1>我是vue组件</h1>
  </div>
</template>

<script>
export default {
    name:'App',
    data(){
        return{

        }
    }
}
</script>

<style scoped>

</style>

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>
    <link rel="stylesheet" href="../src/style.css">
</head>

<body>
    <div>
        <div class="box1"></div>
        <img src="../image/1.jpeg" alt="" srcset="">
    </div>
    <script src="/bundle.js"></script>
    <div id="app"></div>
</body>
</html>

babel.config.js

module.exports = {
    presets: ['@babel/preset-env'],
    plugins: ['@babel/plugin-transform-runtime', '@babel/plugin-proposal-class-properties']
}

postcss.config.js

const autoprefixer = require('autoprefixer')    //导入自动添加前缀的插件
module.exports = {
    plugins: [autoprefixer]  //挂载插件
}

all.less

body{
    background:url(../image/1.jpeg);
    
    img{
        border-radius: 50%;
        width: 500px;
        height: 500px;
    }
}

style.css

.box1{
    width: 100px;
    height: 100px;
    background-color: yellowgreen;
}
.box2{
    transition: 2s;
    transform:translateX(300px) ;
    width: 100px;
    height: 100px;
    background-color: teal;
    border-radius: 50%;
}

总结

通过上面的步骤,其实我们大致能了解了vue脚手架的做的工作,我们可以通过学习webpack,更加了解vue搭建的过程,如果写的有什么错误,欢迎指正

手写webpack配置文件

原文:https://www.cnblogs.com/jzhey/p/12307710.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!