Skip to content

Instantly share code, notes, and snippets.

@sunwu51
Created December 18, 2017 14:32
Show Gist options
  • Save sunwu51/65c8356f4d3116e69df9fa94bc073f9b to your computer and use it in GitHub Desktop.
Save sunwu51/65c8356f4d3116e69df9fa94bc073f9b to your computer and use it in GitHub Desktop.
webpack

Webpack 3.5.5

常用功能速查手册[截止2017/12/18]

1 基础配置

1.1 入口文件

//entry: {[entryChunkName: string]: string|Array<string>}
//单入口: entry: './file.js'
//多入口: entry: {app: './app.js',vendors: './vendors.js'}
const config = {
   entry: {app: './app.js',vendors: './vendors.js'}
};

module.exports = config;

1.2 出口文件

//入口数决定了出口数

//单入口如下
const config = {
  entry: './file.js',
  output: {
    filename: 'bundle.js',
    path: '/home/proj/public/assets'
  }
};
//-------------------------------------------------------------
//多入口如下
{
  entry: {
    app: './app.js',
    search: './search.js'
  },
  output: {
    filename: '[name]-[chunkhash:6].js',
    path: __dirname + '/dist'
  }
}

// 写入到硬盘:./dist/app.js, ./dist/search.js

1.3 loader

//loader配置前需要先安装,例如react中用babel loader需要安装:
//npm install --save-dev 
//babel-core babel-loader babel-preset-es2015 babel-preset-react
const config={
	.........
	module: {
	  loaders: [
	    {
	      test: /\.(js|jsx)$/,//匹配loaders处理文件正则表达式
	      exclude: /node_modules/,//屏蔽不需要处理的文件
	      loader: 'babel-loader?presets[]=es2015&presets[]=react'
	    }
	  ]
	}
}
//或者单独配置规则,根目录下.babelrc
{
  "presets": [
    "react",
    "es2015"
  ]
}

有时候我们需要多个loader配置,如在js中import css文件需要css的loader

npm install --save-dev style-loader css-loader
 module: {
      rules: [
	    {
	      test: /\.(js|jsx)$/,
	      exclude: /node_modules/,
	      loader: 'babel?presets[]=es2015&presets[]=react'
	    },
        {
          test: /\.css$/,
          use: [
            'style-loader',
            'css-loader'
          ]
        },
    ]
}     

1.4 构建目标

默认为web即浏览器环境运行的js,可选值中node则代表nodejs环境运行的js,还有其他可选值不多介绍。

const conf={
	...
	target:"web"
}

1.5 插件

插件直接引入,不需要写代码就会产生自己应有的作用

//这里添加一个webpack自带的uglifyjs插件,用于压缩js代码
//然后添加一个HtmlWebpackPlugin是帮忙生成一个index.html文件,改文件里引入了所有output的js
const webpack = require('webpack');
const HTMLWebpackPlugin = require('html-webpack-plugin');
const conf={
  ...
   plugins:[
	new webpack.optimize.UglifyJsPlugin({
	    compress: {warnings: false}
    }),
    new HtmlWebpackPlugin()
  ]
}

2 进阶主题

2.1 如何选择loader

如果使用了ES6高级语法如import等,那你需要babel的加载器。

如果使用了某种框架(如react)下的jsx语法,那你需要指定babel设置presets[]=es2015&presets[]=react

如果在js中使用import xx.css方式引入css,那你需要style-loadercss-loader,会将改style放入head中。

如果在js中使用import引入图片、字体等,那你需要file-loader,轻松将图或字体混入jsx style写法中。

以上loader可以通过以下指令安装

npm install --save-dev babel-core babel-loader babel-preset-es2015 babel-preset-react
npm install --save-dev style-loader css-loader
npm install --save-dev file-loader

2.2 如何实现代码分块

在多入口的例子中已经实现每个页面的js各自导出,但若俩页面都引用jquery分别导出的两份js中都有jquery的封装,是一种带宽浪费。

公共代码抽取----CommonsChunkPlugin

//利用webpack内部模块CommonsChunkPlugin,实现提取公共js单独输出
//这里name属性指定的就是output中的[name],也可以直接指定filename属性
plugins:[
  new webpack.optimize.CommonsChunkPlugin({
   name: 'common' // Specify the common bundle's name.
  })
]

output: {
  filename: '[name].bundle.js',
  path: path.resolve(__dirname, 'dist')
}

[但是公共代码不代表就是一个库的代码,可能是俩库或者和自己util混合的]

单独剥离第三方库----CommonsChunkPlugin

 entry: {
   bundle: 'app'
   vendor: ['react']
 }

 plugins: [
   new webpack.optimize.CommonsChunkPlugin('vendor',  'vendor.js')
 ]
 //这里['react']能在入口的文件中识别其引入,并将其剥离
 //后面的‘vendor’是之前的键名,vendor.js是生成的文件名

动态加载js---------import webpack.config.js

const HTMLWebpackPlugin = require('html-webpack-plugin');

const config={
    entry:{
        index: './index.js',
    },
    output:{
        filename: "[name]-bundle.js",
        path: __dirname+'/dist'
    },
    plugins:[ new HTMLWebpackPlugin() ]
}
module.exports = config;

index.js

console.log("index")
setTimeout(function(){
	import('./app').then(res=>{
		console.log(res.value)
		res.fun()
    })	
},3000)

app.js

export default {value:12345,fun:()=>{console.log('app')}}

首先加载index.html+index.js,打印index。3s后加载0-bundle.js,打印12345 app。注意这里我们并没有让他输出0-bundle.js,webpack自动从代码中判断出import这个可能加载的项,按照name=0编译出js,等待加载的时机。

这里的setTimeout是事件的一种,实际可以替换为按钮点击,路由跳转等。

上面有个小问题,就是往往我们要用babel-loader加载js,但是一旦用了babel如果不在文件首部使用import就报错,解决方案: yarn add --dev babel-plugin-syntax-dynamic-import

 module: {
        loaders: [
          {
            test: /\.(js|jsx)$/,//匹配loaders处理文件正则表达式
            exclude: /node_modules/,//屏蔽不需要处理的文件
            use:
            [
	            {
	                loader: 'babel-loader',
	                options:{
	                    presets:'es2015',
	                    plugins:['syntax-dynamic-import']
	                }
	            }
            ]
          }
        ]
    }

3 小结

开发中常用的webpack.config.js可以这么写:

const HTMLWebpackPlugin = require('html-webpack-plugin');
const webpack =require('webpack')
const config={
    entry:{
        index: './index.js',
    },
    output:{
        filename: "[name]-bundle.js",
        path: __dirname+'/dist'
    },
    plugins:[
        new webpack.optimize.UglifyJsPlugin({
            compress: {}
        }),            
        new HTMLWebpackPlugin()
    ],
    module: {
        loaders: [
          {
            test: /\.(js|jsx)$/,//匹配loaders处理文件正则表达式
            exclude: /node_modules/,//屏蔽不需要处理的文件
            use: [{
                loader: 'babel-loader',
                options:{
                    presets:'es2015',
                    plugins:['syntax-dynamic-import']
                }
            }
            ]
          },
          {
	          test: /\.css$/,
	          use: [
	            'style-loader',
	            'css-loader'
	          ]
	      },
        ]
    }

}
module.exports = config;

这之前需要安装到dev以下模块

babel-core
babel-loader
babel-preset-es2015
//babel-preset-react
style-loader css-loader
html-webpack-plugin
babel-plugin-syntax-dynamic-import
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment