Webpack工具 - 打包执行中的奇奇怪怪

Webpack 打包文件

虽然,我们可以直接通过命令的来打包,但是推荐创建一个 webpack.config.js 的配置文件来实现更方便和强大的功能。
webpack 命令在运行的时候,默认会读取运行命令所在的目录下的 webpack.config.js 文件,通常我们会在项目的根目录下运行命令和创建配置文件。

打包配置

  • 文件目录列表
    文件列表配置
  • webpack.config.js 文件核心代码
module.exports = {
    // mode: 配置打包出来的文件样式
    // production : 默认 压缩版
    // development: 未压缩
    mode:'production',
    entry:'./src/a.js',
}

核心配置

webpack.config.js文件内部的核心代码

mode 打包之后的模式

指定打包后文件的格式,有三种不同的形式

  • production ( 默认情况 ) 生产模式,文件中的注释、空格等均不会保留
    用于产品上传时使用,内存小
    在这里插入图片描述
  • development 开发模式,文件中的注释等内容会保留
    用于开发人员使用,内存较大
    在这里插入图片描述
  • none 实际效果与开发模式相同
    在这里插入图片描述
entry

指定打包⼊口⽂文件,有三种不同的形式

  • 一对一
    一个入口、一个打包文件
module.exports = {
  entry: './src/a.js'
}

在这里插入图片描述

  • 多对一
    多个入口、一个打包文件
module.exports = {
  entry: [
    './src/a.js',
    './src/list.js',
  ]
}

在这里插入图片描述

  • 多对多
    多个入口、多打包文件
module.exports = {
  entry: {
    'index': "./src/a.js",
    'list': "./src/list.js"
  }
}

在这里插入图片描述

output

修改打包后的文件位置,默认为 dist
即自定义的打包文件存放位置,并不会影响文件内容

// 引入内置的模块( 依赖于 node.js )
const path = require("path"); 

module.exports = {
    mode:'production',
    entry:{
        'index':'./src/a.js',
        'list':'./src/list.js'
    },
    output: {
        // __dirname 当前目录
        // path 必须是绝对路径
        path: path.resolve(__dirname, "memory"),
        // filename: "bundle.js", // 生成的一个包
        filename: "[name].js" // 两个包 [name] 只是占位符
    }
}

在这里插入图片描述

打包文件深化

模块不仅仅只是 js 的文件,webpack 可以把任意文件数据作为模块进行处理
包括:非 js 文本、css、图片等等
打包别的文件需要使用额外的配置 loader

  • index.js 文件中引入 txt 文件
import girl from './data/girl.txt'
console.log(girl)
console.log("我在这里啊,就在这里啊!")
  • webpack.config.js 文件中配置
module.exports = {
    mode: 'production',
    entry: {
        "index":'./src/index.js'
    },
    module: {
        rules: [
            {
                test: /\.txt$/,
                use: {
                    loader: 'raw-loader'
                }
            }
        ]
    }
}
  • 页面效果
    在这里插入图片描述

Loaders

对应引入不同类型的文件打包时,需要不同的 loader
但只是实现了解析,还需要手动引入到页面上

  • 下载对应的 loader npm install --save-dev 对应的loader

  • webpack.config.js 配置

module.exports = {
  ...,
  module: {
      rules: [
      	{
	      	// 正则匹配对相应的指定文件
	        test: /\.(文件后缀)$/,
	        // 使用对应的 loader
	        use: '对应的 loader'
    	}
    ]
	}
}
file loader

把识别出的资源模块,移动到指定的输出⽬目录
并且返回这个资源在输出目录的地址(字符串)
可以用来处理图片资源

  • 下载
    npm install --save-dev file-loader
  • 使用 file-loader解析
module.exports = {
  ...,
  module: {
      rules: [
		{
			test: /\.(png|jpe?g|gif)$/,
            use: {
            	loader: "file-loader",
                options: {
	                // placeholder 占位符 [name] 源资源模块的名称
                    // [ext] 源资源模块的后缀
                    name: "[name]_[hash].[ext]",
                    //打包后的存放位置
                    outputPath: "./images",
                    // 打包后文件的 url
                    publicPath: './images'
                }
            }
    	}
    ]
	}
}

  • 引入到页面
import pic from './data/夏.jpg'
let img = new Image();
img.src = pic;
document.body.appendChild(img);
txt 文件
  • 下载
    npm install --save-dev raw-loader
  • 使用 raw-loader 解析
const path = require("path")
module.exports = {
    mode: 'production',
    entry: {
        "index":'./src/index.js'
    },
    output:{
        path:path.resolve(__dirname,"dist"),
        filename:"[name].js"
    },
    module: {
        rules: [
            {
                test: /\.txt$/,
                use:'raw-loader'
            }
        ]
    }
}
  • 引入到页面
import girl from './data/girl.txt'
console.log(girl)
jpg/png/gif 文件
  • 下载
    npm install --save-dev url-loader
  • 使用 url-loader 解析
const path = require("path")
module.exports = {
    mode: 'production',
    entry: {
        "index":'./src/index.js'
    },
    output:{
        path:path.resolve(__dirname,"dist"),
        filename:"[name].js"
    },
    module: {
        rules: [
            {
                test: /\.(png|jpe?g|gif)$/i,
                use: {
                    loader: 'url-loader',
                    options: {
                        /**
                         * path:路径
                         * name:文件名 可以不写
                         * ext:后缀
                         * */ 
                        // name:'[path][name].[ext]',
                        // 设置打包后的文件位置 
                        outputPath:'/image',
                        // 设置 打包后文件返回的 url
                        publicPath:'./dist/image',
                        // 限制文件的大小,小于 300k 时,直接编译成 16位形式的代码
                        limit:300
                    }
                }
            }
        ]
    }
}
  • 引入到页面
import pic from './data/夏.jpg'
let img = new Image();
img.src = pic;
document.body.appendChild(img);
markdown 文件

需要 html-loader markdown-loader 配合使用

  • 下载
    npm install --save-dev html-loader markdown-loader
  • 使用 html-loader markdown-loader 进行解析
    有先后顺序的区别,执行的顺序是从后往前执行的
const path = require("path")
module.exports = {
    mode: 'production',
    entry: {
        "index":'./src/index.js'
    },
    output:{
        path:path.resolve(__dirname,"dist"),
        filename:"[name].js"
    },
    module: {
        rules: [
            {
                test: /\.md$/,
                // 执行多个 loader ,顺序从后往前
                use:['html-loader','markdown-loader'] 
            }
        ]
    }
}
  • 引入到页面
import tt from './data/2-webpack.md'
document.body.innerHTML = tt;
css 文件

单独使用 css-loader 也可以实现
但是只是实现了解析 css 文件,需要手动实现 css 样式加载到页面

  • 下载
    npm install --save-dev css-loader
  • 使用css-loader进行解析
const path = require("path")
module.exports = {
    mode: 'production',
    entry: {
        "index":'./src/index.js'
    },
    output:{
        path:path.resolve(__dirname,"dist"),
        filename:"[name].js"
    },
    module: {
        rules: [
            {
                test: /\.css$/,
                use:'css-loader'
            }
        ]
    }
}
  • 引入到页面
import cs from './data/cs.css'

// style 标签保存样式
let sty = document.createElement("style");
sty.innerHTML = cs[0][1];
document.head.appendChild(sty);

结合使用 style-loader 可以更简单

  • 下载
    npm install --save-dev css-loader style-loader

  • 使用css-loader style-loader进行解析
    有先后顺序的区别,执行的顺序是从后往前执行的

const path = require("path")
module.exports = {
    mode: 'production',
    entry: {
        "index":'./src/index.js'
    },
    output:{
        path:path.resolve(__dirname,"dist"),
        filename:"[name].js"
    },
    module: {
        rules: [
            {
                test: /\.css$/,
                // 执行多个 loader ,顺序从后往前
                // use:'css-loader',
                /**
                 * style-loader
                 * 直接实现挂载 
                 * */ 
                use:['style-loader',{
                    /**
                     * 单独执行 css-loader
                     * 仅仅是实现了 css 打包识别
                     * 无法实现直接加载到页面,
                     * 还需要保存到 style标签
                     * 然后才能使用
                     * */ 
                    loader:'css-loader',
                    options:{
                        url:true,// 允许借入背景图 默认开启
                    }
                }],
            }
        ]
    }
}
  • 引入到页面
import cs from './data/cs.css'

Plugins

扩展 webpack 本身的一些功能
之前介绍的 webpack 我们会发现将所有的文件都打包成了 js 文件
唯独没有 html ,但是实际操作时 html 也是需要打包起来

HtmlWebpackPlugin

打包结束后自动化生成一个 html 文件,并将打包好的一系列文件加载到 html 文件上

  • npm 下载引入
    npm install --save-dev html-webpack-plugin
  • webpack.config.js 配置
const HtmlWebpackPlugin = require("html-webpack-plugin");
module.exports = {
	...
	plugins: [
    	new HtmlWebpackPlugin({
            title: "App Test",
            /**
             * 打包之后的文件名称 可以获取
             * 
             * <title>
             *  <%=htmlWebpackPlugin.options.title%>
             * </title>
             * 
             * */ 
            // 文件名 app.html
            filename: "app.html",
            // 被打包的 html 文件地址
            template: "./public/index.html"
        }),
  ]
};
  • 打包之后的效果
    在这里插入图片描述
  • 自动获取标题<%=htmlWebpackPlugin.options.title%>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <!-- 打包之后,可以直接获取标题 -->
    <title><%=htmlWebpackPlugin.options.title%></title>
</head>
<body>
</body>
</html>
  • 打包后的 html 文件内容
    html文件
CleanWebpackPlugin

在打包之前先清除之前的压缩包

  • 下载
    npm install --save-dev clean-webpack-plugin
  • webpack.config.js 配置
const {CleanWebpackPlugin} = require('clean-webpack-plugin');
module.exports = {
	...
	plugins: [
    	new CleanWebpackPlugin()
	]
};
mini-css-extract-plugin

代替 style-loader 的存在,提取 CSS 到一个单独的文件中

  • 下载
    npm install --save-dev mini-css-extract-plugin
  • webpack.config.js 配置
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = {
	...
	module: {
		rules: [
	  		{
                test: /\.css$/,
                use:[
                    // 'style-loader',
                    {
                        loader: MiniCssExtractPlugin.loader
                    },
                    {
                    loader:'css-loader',
                    options:{
                        url:true,// 允许借入背景图 默认开启
                    }
                }],
            },
  		]
	},
	plugins: [
    	new MiniCssExtractPlugin({
            filename: './app.css'
        }),
	]
};
sourceMap

我们实际运行在浏览器的代码是通过 webpack 打包合并甚至是压缩混淆过的代码
所生成的代码并不利于我们的调试和错误定位,可以通过 sourceMap 来解决这个问题
sourceMap 本质是一个记录了编译后代码与源代码的映射关系的文件
我们可以通过 webpackdevtool 选项来开启 sourceMap

module.exports = {
	mode: 'production',
	devtool: 'source-map',
  ...
}
  • 打包效果
    在这里插入图片描述

WebpackDevServer

每次的代码修改都需要重新编译打包,刷新浏览器,特别麻烦
我们可以通过安装 webpackDevServer 来改善这方面的体验

  • 下载
    npm install --save-dev webpack-dev-server
  • 启动指令npx webpack-dev-server或者在package.json 中添加 scripts
{
  ...,
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "start": "webpack",
    "server": "webpack-dev-server"
  }
}
  • 修改 webpack.config.js 配置
module.exports = {
	...,
    devServer: {
        // 生成的虚拟目录路径
        contentBase: "./dist",
        // 想要,默认打开的路径
        openPage:'app.html',
        index:'app.html',
        // 自动开启浏览器
        open: true,
        // 开启热更新
  	    hot:true,
  	    // 即使 HMR 不生效,也不去刷新整个页面(选择开启)
        hotOnly:true,
    }
}
  • 热更新开启后
    压缩文件中的内容会被清除
    每次更新新的内容

Proxy

跨域处理
  • 跨域配置文件
import axios from  'axios'
export default async () => {
    let res = await axios({
        url:'/api'
    })
    console.log(res);
} 
  • webpack.config.js 配置
module.exports = {
	...,
    devServer: {
		...,
        // 端口
        port: 8081,
        // 跨域
        proxy:{
            '/api':{
                target:'http://localhost:8989',
            }
        }
    }
}
后端服务器配置
const Koa = require('koa');
const KoaRouter = require('koa-router');
const app = new Koa();
const router = new KoaRouter();

router.get('/', async ctx => {
    ctx.redirect("/api");
    ctx.body = 'api';
});
 
router.get('/api', async ctx => {
    ctx.body = '难受不?!难受就对了';
}); 

app.use( router.routes() );
app.listen(8989);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值