css-loader,less-loader,style-loader 구현
18244 단어 웹 팩 시리즈
less-loader
less-loader.js
let less = require('less');
function loader(source) {
let css;
less.render(source, function (err, r) { // r.css
css = r.css;
});
return css;
}
module.exports = loader;
css-loader
css-loader.js
function loader(source) {
let reg = /url\((.+?)\)/g;
let pos = 0;
let current;
let arr = ['let list = [];'];
while (current = reg.exec(source)) {
let [matchUrl, g] = current;
console.log(matchUrl, g);
let last = reg.lastIndex-matchUrl.length;
arr.push(`list.push(${JSON.stringify(source.slice(pos, last))})`);
pos = reg.lastIndex;
// g require =》 url(require('***'))
arr.push(`list.push('url('+require(${g})+')')`);
}
arr.push(`list.push(${JSON.stringify(source.slice(pos))})`);
arr.push(`module.exports = list.join('')`);
console.log(arr.join('\r
'));
return arr.join('\r
');
}
module.exports = loader;
style-loader
style-loader.js
let loaderUtils = require('loader-utils');
function loader(source) {
// style-loader ,
let str = `
let style = document.createElement('style');
style.innerHTML = ${JSON.stringify(source)};
document.head.appendChild(style);
`;
return str;
}
loader.pitch = function(remainingRequest) {
//
// style-loader less-loader!css-loader!./index.less;
console.log(remainingRequest);
console.log(loaderUtils.stringifyRequest(this, '!!' + remainingRequest));
let str = `
let style = document.createElement('style');
style.innerHTML = require(${loaderUtils.stringifyRequest(this, '!!' + remainingRequest)});
document.head.appendChild(style);
`;
return str;
};
module.exports = loader;
webpack.config.js let path= require('path');
module.exports = {
entry: './src/index.js',
output: {
filename: 'index.js',
path: path.resolve(__dirname, 'dist')
},
mode: 'development',
resolveLoader: {
modules: ['node_modules', path.resolve(__dirname, 'loaders')],
},
devtool: "source-map",
// watch: true,
module: {
// loader ,pre , post , normal
// loader pre +normal + inline + post; ,
rules: [
{
test: /\.less$/,
use: ['style-loader', 'css-loader', 'less-loader']
},
{
test: /(\.png)|(\.svg)/,
use: {
// loader: "file-loader"
loader: "url-loader",
options: {
limit: 1
}
}
},
{
test: /\.js$/,
use: {
loader: "banner-loader",
options: {
text: 'zhangfeng',
filename: path.resolve(__dirname, 'banner.js'),
}
}
}
// {
// test: /\.js$/,
// use: {
// loader: 'babel-loader',
// options: {
// presets: [
// '@babel/preset-env'
// ]
// }
// }
// }
]
}
};
let path= require('path');
module.exports = {
entry: './src/index.js',
output: {
filename: 'index.js',
path: path.resolve(__dirname, 'dist')
},
mode: 'development',
resolveLoader: {
modules: ['node_modules', path.resolve(__dirname, 'loaders')],
},
devtool: "source-map",
// watch: true,
module: {
// loader ,pre , post , normal
// loader pre +normal + inline + post; ,
rules: [
{
test: /\.less$/,
use: ['style-loader', 'css-loader', 'less-loader']
},
{
test: /(\.png)|(\.svg)/,
use: {
// loader: "file-loader"
loader: "url-loader",
options: {
limit: 1
}
}
},
{
test: /\.js$/,
use: {
loader: "banner-loader",
options: {
text: 'zhangfeng',
filename: path.resolve(__dirname, 'banner.js'),
}
}
}
// {
// test: /\.js$/,
// use: {
// loader: 'babel-loader',
// options: {
// presets: [
// '@babel/preset-env'
// ]
// }
// }
// }
]
}
};