打包 CSS/images等资源

Reads: 987 Edit

  • Webpack本身只能处理JavaScript模块,如果要处理其他类型的文件,就需要结合插件来使用,这写插件在Webpack中被称为 Loader(加载器)来进行转换
  • Loader可以理解为模块和资源的转换器,它本身是一个函数,参数接受的是源文件,返回值是转换后的结果
  • 这样,我们就可以通过require或import 来加载任何类型的模块或文件,比如CSS ,图片

1 打包CSS资源文件

创建 demo3项目

1 安装style-loader和css-loader依赖

首先安装相关Loader插件:

  • css-loader 是将css装载到javascript

  • style-loader 是让javascript认识css

npm install --save-dev style-loader css-loader

修改 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> 
    
   <p id="title">aaabbbb</p>
   
      <div id="box1"></div>
      
</body>
</html>

2 .修改 webpack.config.js

//引用Node.js中的path模块,处理文件路径的小工具
const path = require("path");

// 导出一个webpack具有特殊属性配置的对象
module.exports = {
    mode: "development" ,
    //入口
     //入口模块文件路径
    entry:  "./src/main.js" ,
    //出口是对象
    output: {
        //path是一个绝对路径,__dirname 是当前js的绝对路径
        path: path.join(__dirname , "./dist/"), //打包的结果文件存储目录
        filename : "bundle.js"  //打包的结果文件名
    },module:{ //模块
          rules: [  // 规则
             {
                test  : /\.css$/ , //正则表达式,匹配 .css 文件资源
                use: [
                    "style-loader",
                    "css-loader"
                ]
             }  
          ]
    }
}

package.json

{
  "name": "demo3",
  "version": "1.0.0",
  "main": "webpack.config.js",
  "scripts": {
    "build": "webpack --config ./webpack.config.js"
  },
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "css-loader": "^3.4.2",
    "style-loader": "^1.1.3"
  },
  "dependencies": {},
  "description": ""
}

3 在src文件加创建css文件夹,css文件夹下创建 style.css

body{
    background: red;
}

#title {
    color: blue;
}



4 在main.js中引入style.css

// 模块方式导入css,最终会打成js,打包在 bundle.js中
import './css/style.css'

5 重新打包编译

npm run build

打包后,查看bundle.js ,发现已经将css样式以js方式引入了

6 访问index.html 发现背景已经变成红色了。

原理: F12查看 index.html源码后,其实是将css文件内容转成一个javascript模块,然后在运行javascript时,会将样式动态使用<style>标签,放在<head>标签下

2 打包 Images资源

2.1 打包 Images步骤

1 安装 file-loader 依赖

npm install --save-dev file-loader

2 修改webpack.config.js

//引用Node.js中的path模块,处理文件路径的小工具
const path = require("path");

// 导出一个webpack具有特殊属性配置的对象
module.exports = {
    mode: "development" ,
    //入口
     //入口模块文件路径
    entry:  "./src/main.js" ,
    //出口是对象
    output: {
        //path是一个绝对路径,__dirname 是当前js的绝对路径
        path: path.join(__dirname , "./dist/"), //打包的结果文件存储目录
        filename : "bundle.js"  //打包的结果文件名
    },module:{ //模块
          rules: [  // 规则
             {
                test  : /\.css$/ , //正则表达式,匹配 .css 文件资源
                use: [
                    "style-loader",
                    "css-loader"
                ]
             } ,
             {
                test  : /\.(png|svg|jpg|gif)$/ , //正则表达式,匹配 .css 文件资源
                use: [
                    "file-loader"                    
                ]
             }   
          ]
    }
}

3, 修改 style.css

body{
    background: red;
    background-image : url(../images/img.jpg);
}

#box1{
    width: 500px;
    height: 500px;
    background-image : url(../images/img.jpg); 
    background-repeat: no-repeat;
    background-size:  100% 100%;
}

在src目录下新建images文件夹,把图片img.jpg放到这个目录下。

4 打包编译

npm run build

5 访问跟目录下的index.html,背景图并未显示出来

6 问题:

如果直接访问根目录下的index,那么图片资源路径就无法访问到 解决方案: 把index.html放到 dist目录中,但是dist是打包编译后的结果,而非源码,所以把index.html放到dist就不合适,而且如果我们一旦把打包的结果文件名 bundle.js改了之后,则index.html也需要手动修改,综合以上遇到的问题,可以使用一个插件 html-webpack-plugin来解决。

2.2 使用HtmlWebpackPlugin插件

作用: 解决文件路径问题

  • 将index.html打包到bundle.js所在目录
  • 同时也会在index.html中自动的将<script>引入 bundle.js

1 安装插件

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

2 修改webpack.config.js

//引用Node.js中的path模块,处理文件路径的小工具
const path = require("path");
//引入插件
const HtmlwebpackPlugin = require("html-webpack-plugin")

// 导出一个webpack具有特殊属性配置的对象
module.exports = {
    mode: "development" ,
    //入口
     //入口模块文件路径
    entry:  "./src/main.js" ,
    //出口是对象
    output: {
        //path是一个绝对路径,__dirname 是当前js的绝对路径
        path: path.join(__dirname , "./dist/"), //打包的结果文件存储目录
        filename : "bundle.js"  //打包的结果文件名
    },module:{ //模块
          rules: [  // 规则
             {
                test  : /\.css$/ , //正则表达式,匹配 .css 文件资源
                use: [
                    "style-loader",
                    "css-loader"
                ]
             } ,
             {
                test  : /\.(png|svg|jpg|gif)$/ , //正则表达式,匹配 .css 文件资源
                use: [
                    "file-loader"                    
                ]
             }   
          ]
    },
    //配置插件
    plugins: [
        new HtmlwebpackPlugin({
            //此插件作用是将 index.html打包到bundle.js所在目录中
            //同时会在 index.html中自动的在<script>引入 bundle.js
            template : "./index.html"
        })
    ]
}

注意:webpack项目中报错:Error: Cannot find module 'webpack/lib/node/NodeTemplatePlugin' 的解决 办法

如果package.json里没有本地安装webpack. 直接本地安装: npm install webpack --save-dev

3 修改 index.html, 模拟vue页面

<!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> -->
     <!-- 使用了HtmlwebpackPlugin插件后悔自动引入bundle.js-->

       <div id="app">abc</div>
</body>
</html>

4 重新打包

npm run build

运行后会发现dist目录下多了一个index.html,并且文件中自动引入了bundle.js

QQ截图20200223074354

5 运行dist/index.html文件,背景图正常显示了,不要运行了根目录下的 index.html

html引入图片资源

1 安装 url-loader , html-loader 依赖

 npm install --save-dev url-loader
 
  npm install --save-dev html-loader
  

2 修改 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>
        
   <p id="title">aaabbbb</p>

   <div id="box1"></div>

   <img src="./src/images/img.jpg">


</body>
</html>

2 webpack.conf.js

//引用Node.js中的path模块,处理文件路径的小工具
const path = require("path");

//引入插件
const HtmlwebpackPlugin = require("html-webpack-plugin")

// 导出一个webpack具有特殊属性配置的对象
module.exports = {
    mode : "development" ,
    //入口
     //入口模块文件路径
    entry:  './src/main.js' ,
    //出口是对象
    output: {
        //path是一个绝对路径,__dirname 是当前js的绝对路径
        path: path.join(__dirname , "./dist/"), //打包的结果文件存储目录
        filename : "bundle.js"  //打包的结果文件名
    },module:{ //模块
        rules: [  // 规则
           {
              test  : /\.css$/ , //正则表达式,匹配 .css 文件资源
              use: [
                  "style-loader",
                  "css-loader"
              ]
           }   ,
           {
              test  : /\.(png|svg|jpg|gif)$/ , //正则表达式,匹配 文件资源
              loader:  "url-loader"                    
              ,
              options:{
                  // 图片大小小于400KB,就会被base64处理,优点: 简绍请求数量,减轻服务器压力
                  limit : 400 * 1024, 

                  //因为url-loader默认使用 es6模块化解析,而html-loader引入tupianshi commonjs
                  // 解析式会出现问题: [object Module]
                  // 解决: 关闭 url-loader的es6模块化,使用commonjs解析
                  esModule: false ,
                  // 给图片进行重命名
                  // [hash:10].[ext] 取图片的hash值的前10位
                  name : '[hash:10].[ext]'
            }
           }  ,
           {
              test  : /\.html$/ , 
              //处理html文件的img图片,负责引入图片,从而能被打包处理
              loader: "html-loader"  
           }     
        ]
  },
  //配置插件
  plugins: [
      new HtmlwebpackPlugin({
          //此插件作用是将 index.html打包到bundle.js所在目录中
          //同时会在 index.html中自动的在<script>引入 bundle.js
          template : "./index.html"
      })
  ]
}

3 在运行 webpack命令,在 dist/index.html会发现文件

QQ截图20200226181420

关于作者

王硕,网名信平,十多年软件开发经验,业余架构师,精通Java/Python/Go等,喜欢研究技术,著有《PyQt 5 快速开发与实战》《Python 3.* 全栈开发》,多个业余开源项目托管在GitHub上,欢迎微博交流。


Comments

Make a comment

www.ultrapower.com ,王硕的博客,专注于研究互联网产品和技术,提供中文精品教程。 本网站与其它任何公司及/或商标无任何形式关联或合作。