Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

webpack4学习笔记(八) #35

Open
Rashomon511 opened this issue Jul 26, 2019 · 0 comments
Open

webpack4学习笔记(八) #35

Rashomon511 opened this issue Jul 26, 2019 · 0 comments
Labels

Comments

@Rashomon511
Copy link
Owner

编写一个loader

loader简单来说就是一个函数,通过一个函数参数接受到源代码,并在函数内部对代码作出变更
newLoader.js

module.exports = function (source) { // source代表的是源代码
    return source.replace('world', ‘wang’) // 将代码中的world替换成wang
}

此时也需要在webpack.config.js中进行配置

const path = require('path');

module.exports = {
    mode: 'development',
    entry: {
        main: './src/index.js'
    },
    module: {
        rules: [{
            test: /\.js/,
            use: [
                path.resolve(__dirname, './loaders/newLoaders.js') //  使用编写的loader
            ]
        }]
    },
    output: {
        path: path.resolve(__dirname, 'dist'),
        filename: '[name].js'
    }
}

loader的使用还可以通过对象的形式使用例如

            use: [
                {
                    loader: path.resolve(__dirname, './loaders/newLoaders.js'),
                    options: {
                        name: 'Wang'
                    }
                }
            ]

loader有两种方式获取options中传递的参数

// 通过this.query访问参数
module.exports = function (source) {
    return source.replace('world', this.query.name)
}
// 通过loader-utils处理参数
const loaderUtils = require('loader-utils');
module.exports = function (source) {
    const options = loaderUtils.getOptions(this)
    return source.replace('world', options.name)
}

如果想要返回err, 处理后源代码,source,或者其他内容,那么可以使用this.callback

const loaderUtils = require('loader-utils');
module.exports = function (source) {
    const options = loaderUtils.getOptions(this)
    const result = source.replace('world', options.name)
    this.callback(null, result);
}

如果想要在函数内部做异步处理那么可以使用this.async()

const loaderUtils = require('loader-utils');
module.exports = function (source) {
    const options = loaderUtils.getOptions(this)
    const result = source.replace('world', options.name)
	const callback = this.async(); // 声明一下内部有异步操作

	setTimeout(() => {
		const result = source.replace('dell', options.name);
		callback(null, result);
	}, 1000);
}

如果我们有多个loader需要使用,我们可以通过resolveLoader来统一使用loaders文件中loader
如下配置

       ....
	resolveLoader: {
		modules: ['node_modules', './loaders']
	},
	module: {
		rules: [{
			test: /\.js/,
			use: [
				{
					loader: 'replaceLoader',
				},
				{
					loader: 'newloaders',
					options: {
						name: 'Wang'
					}
				},
			]
		}]
	},
        ....

编写loader需要注意的是不要使用箭头函数,会导致this指向错误

编写一个Plugin

plugin插件是一个类,如下是一个plugin的基本结构

class CopyrightWebpackPlugin {
	constructor(options){
		console.log(options) // options是插件传入的参数
	}
	apply(compiler) { // compiler是webpack的实例}
}
module.exports = CopyrightWebpackPlugin;

结构写好之后,需要webpack中引入使用插件

const path = require('path');
const CopyRightWebpackPlugin = require('./plugins/copyright-webpack-plugin');

module.exports = {
	mode: 'development',
	entry: {
		main: './src/index.js'
	},
	plugins: [
		new CopyRightWebpackPlugin()
	],
	output: {
		path: path.resolve(__dirname, 'dist'),
		filename: '[name].js'
	}
}

接下啦完善apply, 利用打包过程中emit的时刻来进行处理,添加一个copyright.txt文件,

	apply(compiler) { // compiler是webpack的实例

		compiler.hooks.compile.tap('CopyrightWebpackPlugin', (compilation) => {
			console.log('compiler');
		})

		compiler.hooks.emit.tapAsync('CopyrightWebpackPlugin', (compilation, cb) => {
			compilation.assets['copyright.txt']= {  // compilation.assets是打包生成的文件,可以向其中添加内容
				source: function() {
					return 'copyright by dell lee'
				},
				size: function() {
					return 21;
				}
			};
			cb();
		})
	}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant