Fork me on GitHub

webpack

总结一下webpack

webpack各种配置

  1. webpack-dev-server

webpack-dev-server用来创建本地服务器,监听你的代码修改,并自动刷新修改后的结果。
这里配置devServer就是配置webpack-dev-server的。

1
2
3
4
5
6
7
devServer: {
contentBase: path.join(__dirname, "dist"), // 本地服务器所加载的页面所在的目录
compress: true,
port: 9000, // 配置端口
inline: true, // 设置为true,源文件发生改变自动刷新页面
historyApiFallback: true // 依赖HTML5 history API,如果设置为true,所有的页面跳转指向index.html
}

context

这是entry配置项的根目录(绝对路径)。如果output.pathinfo也设置了,它的pathinfo是基于这个根目录。

context:__dirname + './src'

entry

有三种方式 字符串 数组 对象

  1. 一个入口文件:字符串

    1
    entry: "./src/js/root.js"
  2. 多个入口文件打包成一个:数组

    1
    entry:['./entry1','./entry2']
  3. 多入口文件打包多个文件:对象

    1
    2
    3
    4
    entry: {
    app:"./src/js/root.js",
    app2:"./src/js/root2.js",
    }

    注意 output中需要使用占位符等方法来解决导出的模块文件相互覆盖的问题:
    占位符:

    [name] => app,app2
    [hash] => 打包的hash值
    [chunkhash] => chunk的hash值
    

output

1
2
3
4
5
6
7
output: {
filename: './dist/js/[name].bundle.js'
}
webapck3.0.0+开始,一定要使用绝对路径
path:path.join(__dirname)+'/dist' => 没有 ./ 而是 /

配置多个入口同时配置多个出口文件,可以用[name].js

1
2
3
output: {
filename: '[name].js'
}

resolve

1
2
3
4
5
6
// 用来配置应用层的模块解析,即要被打包的模块
resolve: {
// 第一项扩展非常重要,千万不要忽略,否则经常出现模块无法加载错误
extensions: ['', '.js', '.es6', '.vue']
}
//通过以上配置,webpack会自动为请求的文件添加后缀名,从而保证请求的路径正确无误。

Loader

module.loaders => module.rules webpack 4以上。

loader的作用:

1、实现对不同格式的文件的处理,比如说将scss转换为css,或者typescript转化为js

2、转换这些文件,从而使其能够被添加到依赖图中

1
2
3
4
5
6
7
{
test: /\.js?$/, // 匹配所处理文件的扩展名的正则表达式(必须)
exclude: /(node_modules)/, // 手动添加处理的文件,屏蔽不需要处理的文件(可选)
loader: 'babel-loader', // loader的名称(必须)
query: { // 为loaders提供额外的设置选项
presets: ['react', 'es2015']
}

这里介绍几个常用的loader:

babel-loader: 让下一代的js文件转换成现代浏览器能够支持的JS文件。

babel有些复杂,所以大多数都会新建一个.babelrc进行配置

css-loader,style-loader:两个建议配合使用,用来解析css文件,能够解释@import,url()如果需要解析less就在后面加一个less-loader

file-loader: 生成的文件名就是文件内容的MD5哈希值并会保留所引用资源的原始扩展名

url-loader: 功能类似 file-loader,要先下载file-loader

rules => 4.0以上用 rules use

用过的loader

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
rules: [ // 规则
{
test: /\.vue$/,
loader: 'vue-loader'
},
{
test: /\.jsx$/,
loader: 'babel-loader'
},
{
test:/\.js$/,
exclude:path.resolve(__dirname,'node_modules'),
include:path.resolve(__dirname,'src'),
loader:'babel-loader'
},
{
test: /\.ejs$/,
loader: 'ejs-loader'
},
{
test:/\.css$/,
use:[
style-loader,
css-loader
]
},
{
test: /\.styl/,
use: [
'style-loader',
'css-loader',
{
loader: 'postcss-loader',
options: {
sourceMap: true
}
},
'stylus-loader'
]
},
{
test:/\.less$/,
use: [
"style-loader",
"css-loader",
{
loader: "postcss-loader"
},
"less-loader"
]
},
{
test:/\.scss$/,
use: [
"style-loader",
"css-loader",
"postcss-loader",
"less-loader"
]
},
{
test: /\.(gif|jpg|jpeg|png|svg)$/,
use: [
{
loader: 'url-loader', // 还要依赖于file-loader
options: {
limit: 1024, // 文件小于1024字节,转换成base64编码,写入文件里面
name: '[name]-output.[ext]'
}
}
]
}
]

postcss-loader

配置postcss.config.js
1
2
3
4
5
6
7
const autoprefixer = require('autoprefixer');
// autoprefixer CSS代码加浏览器前缀
module.exports = {
plugins: [
autoprefixer()
]
};

.babelrc => 配置 babel 转义的文件

1
2
3
4
5
6
7
8
{
"presets": [
"env" // babel-preset-env 转译es6的插件
],
"plugins": [
"transform-vue-jsx" // 解析vue中的jsx
]
}

Plugins

HtmlWebpackPlugin 打包html页面

作用: 依据一个简单的index.html模版,生成一个自动引用你打包后的js文件的新index.html

var HTMLWebpackPlugin = require(‘html-webpack-plugin’)
plugins: [
new htmlWebpackPlugin({
filename: ‘./dist/index.html’, => 打包后的目录 注意:output中的path会影响的
template: ‘index.html’, => 要打包的html名称
inject: ‘body’, => output 打包后的js文件在 body标签中引入
title:’title’, => 可以用ejs语法获取到,
minify:{
removeComments:true,
collapseWhitespace:true
},
chunks:[‘a’,’c’],
excludeChunks:[‘a’,’b’] // 不引用 ‘a’,’b’ 与chunks不同时用
})
]
HotModuleReplacementPlugin: 它允许你在修改组件代码时,自动刷新实时预览修改后的结果注意永远不要在生产环境中使用HMR。

多页面打包
就是多个 new htmlWebpackPlugin();
想要引用不同的js,则改变 chunk 

extract-text-webpack-plugin => 单独打包css

const ExtractPlugin = require('extract-text-webpack-plugin');

config.module.rules.push({
    test: /\.styl/,
    use: ExtractPlugin.extract({
        fallback: 'style-loader',
        use: [
            'css-loader',
            {
                loader: 'postcss-loader',
                options: {
                    sourceMap: true
                }
            },
            'stylus-loader'
        ]
    })
});

config.plugins.push(
    new ExtractPlugin('styles.[contentHash:8].css')    
);

如果报错Tapable.plugin is deprecated. Use new API on `.hooks` instead
则下载 extract-text-webpack-plugin@next

压缩

1
2
var BabiliPlugin = require("babili-webpack-plugin");
new BabiliPlugin()

这时output只小了一些。

再将入口分开

1
2
3
4
entry: {
app:"./src/js/root.js",
vendor:['react'],
}
1
2
3
new webpack.optimize.CommonsChunkPlugin({
name:'vendor', //=>生成vendor.js
})

性能检测

1
"stats": "webpack --env production --profile --json > stats.json"

生成json文件,可以性能检测了

网址:
(https://chrisbateman.github.io/webpack-visualizer/);
(http://webpack.github.io/analyse/#home);
(https://alexkuz.github.io/webpack-chart/);
(https://alexkuz.github.io/stellar-webpack/);

启动

1
2
3
"start": "webpack-dev-server --env development",
"build": "webpack -p",
"stats": "webpack --env production --profile --json > stats.json"

打包发布 build上线 / dev开发

if(isDev){
  config.devServer = {
    port:8000,
    host:'0.0.0.0',
    overlay:{
      errors:true
    },
    hot:true
  }
  config.plugins.push(
    new webpack.HotModuleReplacementPlugin(), //热更新
    new webpack.NoEmitOnErrorsPlugin()
  )
  config.module.rules.push(
    {
      test:/\.styl/,
      use: [
          'style-loader',
          'css-loader',
          {
              loader: 'postcss-loader',
              options: {
                  sourceMap: true
              }
          },
          'stylus-loader'
      ]
    }
  )
} else {
  config.entry = {   // 将所用到的类库单独打包
      app: path.join(__dirname, 'src/index.js'),
      vendor: ['vue']
  };
  config.output.filename = '[name].[chunkhash:8].js';
  config.module.rules.push({
      test: /\.styl/,
      use: ExtractPlugin.extract({
          fallback: 'style-loader',
          use: [
              'css-loader',
              {
                  loader: 'postcss-loader',
                  options: {
                      sourceMap: true
                  }
              },
              'stylus-loader'
          ]
      })
  });
  config.plugins.push(
      new ExtractPlugin('styles.[contentHash:8].css')  
  );
}

模块安装

提示 invariant,babel-messages,repeating 没有找到,要全局安装,不然会陷入 无限循环

-------------本文结束感谢您的阅读-------------