Webpack基本配置介绍

webpack基本配置的介绍

准备步骤

  • 初始化
//新建文件夹,文件夹内执行命令
npm init
//局部下载webpack
npm install webpack  --save-dev
  • 建立相关的文件夹,如src,img,本例中:dist存放打包后文件,src下分为script和style分别存放js文件和css文件;
  • 创建配置文件
    • 根目录下创建webpack.config.js
//使用commonjs引入
module.exports ={
  entry: './src/script/main.js',
    output: {
    //webpack3要求绝对路径
        path: __dirname + '/dist/js',
        filename: 'bundle.js'
    }
}
  • 修改package.json里的
"scripts": {
  "test": "echo \"Error: no test specified\" && exit 1",
  "webpack": "webpack --config webpack.config.js --progress --display-modules --colors --display-reasons"
}
  • 运行webpack,成功打包

  • webpack.config.js的作用

    • 可以不命名为webpack.config.js,但是webpack执行时是找不到配置文件的,所以如果命名为webpack.dev.config.js,那么要有一个配置webpack --config webpack.dev.config.js,执行npm run webpack才会成功。

entry和output配置

entry配置

  • entry是指需要打包的文件;
  • entry有几种使用方法:
    • 字符串
entry:__dirname+'/src/script/main.js'
//对应
output:{
  path:__dirname+'/dist/js',
  filename:'bundle.js'
}
  • 数组
entry:[
  __dirname+'/src/script/main.js',
  __dirname+'/src/script/a.js'
]
//对应
output:{
  path:__dirname+'/dist/js',
  filename:'bundle.js'
}
  • 对象
entry:{
        main:__dirname+'/src/script/main.js',
        a:__dirname+'/src/script/a.js'
    }
//对应
output:{
  path:__dirname+'/dist/js',
  filename:'[name]-[hash].js'
}
//or 
output:{path:__dirname+'/dist/js',filename:'[name]-[chunkhash].js'}

output的配置

  • output是指打包生成的文件
  • entry中输入多个chunk时,为确保文件名唯一避免相互覆盖使用占位符命名filename;
  • 三种占位符
    • [name]是chunk的name;
    • [hash]是本次打包的hash值,hash值相同;
    • [chunkhash]是每个chunk的hash值,不同文件同次打包不相同,保证文件的唯一性,只有改变文件中的内容时hash才变化,未做改变的文件hash值不变;
    • [ext]是源文件的后缀名占位符

plugin插件

处理html的插件

html-webpack-plugin

  • 使用html-webpack-plugin插件来解决,webpack.config.js的出口文件名用占位符自动生成的js打包文件名([chunkhash])每一次都不一样的问题;
var htmlWebpackPlugin = require('html-webpack-plugin')
//modules.exprots中的添加插件配置
plugins: [
    //html中引入script,如果是hash或者chunkhash生成的js,则src每次都要修改,避免修改的方法就是使用webpack的插件
    new htmlWebpackPlugin()
]
  • 此时可以将html中引入的js文件自动进行更改,而不用每次生成都要修改生成的hash值;
<script type="text/javascript" src="main-031075bb272d3409c40c.js"></script>
<script type="text/javascript" src="m-031075bb272d3409c40c.js"></script>
  • 但是此时在dist中生成的打包后的html和原本的html文件没有任何的关联,为了将其进行关联,可在插件对象中传入参数:
new htmlWebpackPlugin({
  //此时会默认找到根目录下的index.html文件
  template: 'index.html'
})
  • 为了使得js和html文件不打包到一起,可以在配置的output中进行修改:
output: {
      path: __dirname + '/dist',
      filename: 'js/[name]-[hash].js'
  },
  • 在配置文件webpack.config.js的插件对象中传入的参数,可以使用ejs在index.html中获取到
new htmlWebpackPlugin({
      //添加
      title: 'webpack is good'
  })

//index.html中使用ejs
<head>
    <meta charset="UTF-8">
    <title>
        <%= htmlWebpackPlugin.options.title %>
    </title>
</head>
  • 在htmlWebpackPlugin对象中添加minify配置,是对html的代码进行压缩的配置;
//对对象上代码进行压缩
minify: {
    //参考https://www.npmjs.com/package/html-webpack-plugin
    //删除注释
    removeComments: true,
    //删除空格
    collapseWhitespace: true
}
  • 如果需要将相同的的html进行不同的打包,则可以创建多个htmlWebpackPlugin对象
plugins: [
        //html中引入script,如果是hash或者chunkhash生成的js,则src每次都要修改,避免修改的方法就是使用webpack的插件
        new htmlWebpackPlugin({
            //关联原始html模板文件
            template: 'index.html',
            //指定唯一的html名称[chunhash]
            filename: 'a.html',
            //设置js脚本在head还是body里
            inject: 'head',
            title: 'this is a',
            //对象上代码进行压缩
            minify: {
                //参考https://www.npmjs.com/package/html-webpack-plugin
                //删除注释
                removeComments: true,
                //删除空格
                collapseWhitespace: true
            }
        }),
        new htmlWebpackPlugin({
            //关联原始html模板文件
            template: 'index.html',
            //指定唯一的html名称[chunhash]
            filename: 'b.html',
            //设置js脚本在head还是body里
            inject: 'head',
            title: 'this is b'
        }),
        new htmlWebpackPlugin({
            //关联原始html模板文件
            template: 'index.html',
            //指定唯一的html名称[chunhash]
            filename: 'c.html',
            //设置打包成的模块,是插入在页面的head还是body里
            inject: 'body',
            title: 'this is c'
        })
    ]
  • 倘若有多个js,而且不同的js被不同的html需要,name使用chunks:['main','a'],表示引入的js是哪些;
  • 也可以使用excludeChunks,来指定排除哪些js不用;
  • 此时可以引入不同的js文件,但是是通过script标签中的src属性获得的,这样获得的缺点是要发送多次请求。为了减少向服务器发送的请求,可以使用内嵌式:
//修改webpack.config.js里options中的
inject: false

//在index.html的head中添加
<script type="text/javascript">
    <%= 
    compilation.assets[htmlWebpackPlugin.files.chunks.main.entry.substr(htmlWebpackPlugin.files.publicPath.length)].source() %>
</script>
//讲解:htmlWebpackPlugin.files.chunks可以得到所有依赖的js文件,其中入口js文件就htmlWebpackPlugin.files.chunks.main.entry取到,但是此时的js带着‘http://’,所以,使用htmlWebpackPlugin.files.publicPath.length来截取后面非上线的文件路径,便可得到要插入html中的js代码。而compilation.assets是webpack的一个语法,不了解。

//index.html中的body里面添加,就是指除了入口文件main.js之外,其他文件仍使用script标签来引入,即使用外链式引入。
 <% for(var k in htmlWebpackPlugin.files.chunks){ %>
    <% if(k !== 'main'){ %>
        <script type="text/javascript" src="<%= htmlWebpackPlugin.files.chunks[k].entry %>"></script>
    <% } %>
  <% } %>

loader加载器

  • 学习网址:https://webpack.js.org/concepts/loaders/
  • Webpack 本身只能处理原生的js模块,但是loader转换器可以将各种类型的资源转换成js模块。这样,任何资源都可以成为Webpack可以处理的模块。

使用loader的三种方式

  • 在文件中直接引入loader文件,es6的语法
//es6的语法
import Styles from 'style-loader!css-loader?modules!./styles.css';
//commonjs语法
require('style-loader!css-loader?modules!./styles.css')
  • 在命令行界面使用的方式CLI
//直接执行
webpack --module-bind jade-loader --module-bind 'css=style-loader!css-loader'
  • 在配置文件中使用loader
module: {
    rules: [
      {
        <!-- 首先对资源一个正则匹配 -->
        test: /\.css$/,
        <!-- 匹配成功后会使用多个loader对其进行处理 -->
        use: [
          { loader: 'style-loader' },
          {
            loader: 'css-loader',
            options: {
              modules: true
            }
          }
        ]
      }
    ]
  }

babel

  • Babel通过语法转换器支持最新版本的JavaScript。这些插件允许你立刻使用新语法,无需等待浏览器支持。
  • 在src文件夹下创建component文件夹,component里面创建layer组件,组件里有js、css、html文件;
  • 在src文件夹中创建入口js文件,app.js;
//app.js中引入html
import layer from './component/layer/layer.js'
const App = function() {
    console.log(layer)
}
new App()

//layer.js中渲染模板
import tpl from './layer.html'
function layer() {
    return {
        name: 'layer',
        tpl: tpl
    }
}
export default layer;
  • 安装babel转化es6的代码npm install --save-dev babel-loader babel-core(webpack3版本)
  • 使用babel加载器将es6的语法进行转化,转化时要指定参数,方式有三种:
    • 使用配置指定
//在配置webpack.config.js中添加
module: {
        rules: [{
            test: /\.js$/,
            loader: "babel-loader",
            //加快打包速度的配置
            //排除范围
            exclude: __dirname + '/node_modules/',
            //babel-loader的处理范围
            include: '/src/',
            //webpack3中使用options代替query
            options: {
                'presets': ['env']
            }
        }]
    }
  • 在package.json中添加
"babel":{
  "presets":["env"];
}
  • 根目录下创建.babelrc文件
{
  "presets": ["env"]
} 

使用node的path方法

  • 注意,使用path.resolve时,拼接的文件名称字符串内没有斜杠
//引入node的path方法
var path = require('path');

//使用
exclude: path.resolve(__dirname, 'node_modules'),
include: path.resolve(__dirname, 'src'),

处理css文件的loader

css-loader和style-loader

  • 安装npm i style-loader css-loader --save-dev
  • 在src下面创建css文件夹,创建common.css文件,写入内容;
  • 在配置中写入css的loader配置
{
    test: /\.css$/,
    use: [
        { loader: 'style-loader' },
        {
            loader: 'css-loader',
            options: {
                modules: true
            }
        }
    ]
}

postcss-loader

  • 安装:npm i postcss-loader --save-d
  • postCSS是一种处理css的工具,比如可以支持变量和混入(mixin),增加浏览器相关的声明前缀,或是把使用将来的 CSS 规范的样式规则转译(transpile)成当前的 CSS 规范支持的格式。
  • postcss-loader可以补全css代码的兼容性前缀;
  • 在web对postcss进行配置,需下载npm i postcss-import autoprefixer --save-d
{
    test: /\.css$/,
    use: [
        'style-loader',
        {
            loader: 'css-loader',
            //importLoaders: 1的作用:处理 .css文件中使用@import引用进来的文件,指css-loader后指定数量的loader处理import引用进来的资源;
            options: { modules: true, importLoaders: 1 }
        },
        {
            loader: 'postcss-loader',
            options: {
                plugins: (loader) => [
                    require('postcss-import')({ root: loader.resourcePath }),
                    require('autoprefixer')(), //CSS浏览器兼容
                ]
            }
        }
    ]
},

less-loader

  • 安装npm i less-loader less --save-dev
  • 直接在对css配置的loader中加入less文件的规则
{
    test: /\.less$/,
    use: ['style-loader',
        {
            loader: 'css-loader',
            options: { modules: true, importLoaders: 1 }
        },
        {
            loader: 'postcss-loader',
            options: {
                plugins: (loader) => [
                    require('postcss-import')({ root: loader.resourcePath }),
                    require('autoprefixer')(), //CSS浏览器兼容
                ]
            }
        },
        {
            loader: "less-loader" // compiles Less to CSS 
        }
    ]
}
  • 如果是sass文件和less文件同理;

webpack处理模板文件

  • layer.html是模板文件;webpack处理模板文件的方法有两种:
    • 将模板文件当成一个字符串进行处理;
    • 将模板文件当成已经编译好的模板的处理函数;

webpack处理html文件

  • 如果模板是html文件,那么需要安装html-loader(前面已安装);
    • 在app.js中引入layer.js文件,在layer.js中引入layer.html模板,webpack会将模板直接打包插入到index.html中
//app.js中
//引入css
import './css/common.css'
//引入入口js文件
import Layer from './component/layer/layer.js'

const App = function() {
    // const NUM = 1
    // alert(NUM)
    // console.log(layer)
    var dom = document.getElementById('app');
    var layer = new Layer();
    dom.innerHTML = layer.tpl;
}
new App();

//layer.js中
import './layer.less'
//引入模板
import tpl from './layer.html'

function layer() {
    return {
        name: 'layer',
        tpl: tpl,
    }
}
export default layer

//webpack.config.js中加入
{
    test: /\.html$/,
    use: {
        loader: 'html-loader'
    }
},

webpack处理ejs或tpl文件

  • 如果模板是ejs或者tpl文件,那么需要安装ejs-loader npm install ejs-loader --save-dev
  • layer.js载入ejs模板时,返回的是一个function,这时的import tpl from ‘./layer.tpl’;中的tpl代表的不再是字符串,表示的是一个已经编译过的函数;
  • 操作,(注意将layer.js中引入的html文件更改成tpl文件)
//layer.tpl中
<div class="layer">
    <div>this is
        <%= name %> layer</div>
    <% for (var i=0;i<arr.length; i++) {%>
        <%= arr[i] %>
            <% } %>
</div>

//app.js中插入的模板不再是一个字符串,而是一个函数,函数需要传参数
dom.innerHTML = layer.tpl({
    name: 'join',
    arr: ['apple', 'xiaomi', 'vivo', 'oppo']
});

webpack处理图片或者其他文件

图片文件的处理

在css中使用相对路径的图片生成背景

//common.css修改
html,
body {
    padding: 0;
    margin: 0;
    //使用相对路径
    background-image: url("../assets/人生1.jpg");
}

//webpack.config.js中添加
{
    test: /\.(png|jpg|gif|svg)$/i,
    use: {
        loader: "file-loader"
    }
}
  • 打包,可看到运行后的图片显示在页面上

在html中引入相对路径图片

  • 在body中插入img标签
//index.html文件
<body>
    <!-- <h1>
        这是html模板
    </h1> -->
    //插入图片
    <img src="./src/assets/人生1.jpg" />
    <div id="app"></div>
</body>
  • 编译打包后,图片可以自动找到,绝对定位也会是一样;

在模板中引入图片

  • 绝对路径引入图片,打包后可以直接找到;
  • 相对路径的话,打包后图片加载失败;如果想要使用相对路径引入图片,那么需要在src中使用require来引入图片;
//相对路径错误引用
<img src='../../assets/人生1.jpg'/>

//相对路径正确引用
<img src="${require('../../assets/人生1.jpg')}"/>

改变图片打包后的输出地址

{
    test: /\.(png|jpg|gif|svg)$/i,
    use: {
        loader: "file-loader",
        //插入参数
        options: {
            name: 'assets/[name]-[hash:5].[ext]'
        }
    }
}

处理其他文件

  • 安装npm i url-loader --save-d
  • url-loader和file-loader相似,但是url-loader可以指定limit参数。
  • url-loader可以指定一个limit参数,当图片大于这个参数,则webpack会将图片直接丢给file-loader处理,当其小于指定的limit参数时,url-loader就会直接对其进行处理,转为base64编码;
{
    test: /\.(png|jpg|gif|svg)$/i,
    use: {
        loader: "url-loader",
        options: {
            limit: 30000,
            name: 'assets/[name]-[hash:5].[ext]'
        }
    }
}
  • 使用url-loader会有一种代码的冗余,无论在哪里引用,都会使得引用处多一串代码;

压缩文件

  • 安装npm install image-webpack-loader --save-dev
  • 配置修改,将limit设置的小一点可看出效果
{
    test: /\.(png|jpg|gif|svg)$/i,
    use: [{
            loader: "url-loader",
            options: {
                limit: 100,
                name: 'assets/[name]-[hash:5].[ext]'
            }
        },
        {
            loader: 'image-webpack-loader'
        },
    ]
}
  • 原本打包后25.5KB的图片变成18.6KB了;
  • image-webpack-loader有很多的参数,可以针对不一样的图片类型进行不同的图片优化;
  • 官网:https://www.npmjs.com/package/image-webpack-loader

猜你喜欢

转载自blog.csdn.net/mutouafangzi/article/details/79377917