http для браузера
socket для telnet
udp для передачи видео
tls для защищенных соединений
// Server and Client
var fs = require('fs');
var writeStream = fs.createWriteStream('client-logs.txt');
var http = require('http');
var server = http.createServer();
server.on('request', function (request, response) {
console.log(request.method);
console.log(request.url);
console.log(request.headers);
request.on('data', function (data) {
writeStream.write(data);
});
request.on('end', function () {
writeStream.end();
});
response.setHeader('Content-Length', '1000');
response.removeHeader('Max-Length', '10');
response.writeHead(200, 'OK', {'Content-Type': 'text/html'});
response.write('Hi');
response.end('Bye');
server.close();
});
server.listen(80, '127.0.0.1', function (error) {
if (error) {throw error;}
console.log('Server started at 127.0.0.1:80');
});
var options = {
host: "www.google.com",
port: 80,
path: "/upload",
method: "POST",
agent: new Agent({
maxSockets: 10
})
};
var request = http.request(options);
request.on('response', function (response) {
console.log('STATUS:', response.statusCode);
console.log('HEADERS:', response.headers);
console.log(response.httpVersion);
response.setEncoding('utf8');
response.on('data', function (chunk) {console.log(chunk);});
response.on('end', function (chunk) {console.log('END');});
});
request.on('socket', function (socket) {
socket.emit('agentRemove');
});
request.write('data');
request.end();
// Transmission control protocol TCP Server - Use with command line Telnet
// socket умеет и читать данные и писать данные,
// то есть и принимать их on('data'), on('end')
// и отсылать write(data), end(data)
require('net').createServer(function (socket) { // new connection
socket.on('data', function(data) {
// got data
});
socket.on('end', function(data) {
// connection closed
});
socket.write('Some string');
}).listen(4001);
// telnet 127.0.0.1 4001
var server = require('net').createServer();
var connections = []; // Request connections
server.on('connection', function (socket) {
connections.push(socket);
socket.setEncoding('utf8');
socket.on('data', function(data) {
// got data
console.log('got:', data.toString());
connections.forEach(function(otherSocket) {
if (otherSocket !== socket) {
otherSocket.write(data);
}
});
if (data.trim().toLowerCase() === 'quit') {
socket.write('Bye bye!');
socket.end();
} else {
socket.write(data);
}
});
socket.on('end', function(data) {
// connection closed
console.log('Client connection ended');
});
socket.on('close', function() {
console.log('connection closed');
var index = connections.indexOf(socket);
connections.splice(index, 1); // remove closed socket connections
});
socket.on('error', function(error) {
console.log(error);
});
socket.pause();
socket.resume();
socket.write('Some string');
socket.end('Bye');
});
// socket.setKeepAlive(true) periodically sends an empty packet to keep the connection alive
// whereas socket.setTimeout() is used to define a local inactivity timeout
server.setKeepAlive(true, 10000); // keep the connection alive on both peers, delay 10 seconds before next send
server.setTimeout(60000); // servert timeout 1 minute
server.on('timeout', function() {
server.write('idle timeout, disconnecting, bye!');
server.end();
});
// socket.setTimeout(60000, function() { // альтернативная запись таймаута
// socket.end('idle timeout, disconnecting, bye!');
// });
server.setNoDelay(true); // force data to be sent immediately after each write command socket.write()
server.on('error', function (error) {
throw error;
});
server.on('close', function () {
console.log('Server is now closed');
});
server.on('listening', function () {
console.log('Server started at 127.0.0.1:4001');
});
server.listen(4001, '127.0.0.1');
setTimeout(function () {
server.close();
}, 5000);
// telnet localhost 4001
var ws = require('fs').createWriteStream('mysocketdump.txt');
require('net').createServer(function(socket) {
socket.pipe(ws); // Write data from telnet into file
}).listen(4001);
// telnet localhost 4001
require('net').createServer(function(socket) {
var rs = require('fs').createReadStream('mysocketdump.txt');
rs.pipe(socket); // Send text from file to telnet
}).listen(4001);
// Transmission control protocol TCP Client
var net = require('net');
var host = "www.google.com";
var port = 4000;
var client = net.createConnection(port, host, function (response) {
console.log('We have a new connection');
});
client.once('connect', function (response) {
console.log('We have a new connection');
response.setEncoding('base64');
response.on('data', function (data) {
console.log('some data has arrived:', data);
});
});
client.on('error', function (error) {
console.error('this error happened:' + error.message + ', code: ' + error.code);
});
client.on('close', function() {
console.log('connection got closed, will try to reconnect');
});
client.write('here is a string for you!');
client.end();
// Datagram Server
// node udp_server_1.js
// echo hello | nc -u 0.0.0.0 4000
// This call sends a UDP packet with hello to the local host port 4000.
// Server output that’s something like the following:
// server got message: hello
var dgram = require('dgram');
var server = dgram.createSocket('udp4'); // UDP over IPv4
server.on('message', function (message, rinfo) { // rinfo - information about message sender (remote info)
console.log('server got message: ' + message + ' from ' + rinfo.address + ':' + rinfo.port);
server.send(message, 0, message.length, rinfo.port, rinfo.address, function() {
// you can reuse the message buffer
}); // Send message to message to a specifi c address and port.
});
server.on('listening', function() {
var address = server.address();
console.log('server listening on ' + address.address + ':' + address.port);
});
var port = 4000;
server.bind(port);
// Datagram Client
var dgram = require('dgram');
var client = dgram.createSocket('udp4'); // UDP over IPv4
client.on('message', function(message) {
console.log('Got message back from server:', message.toString());
});
var port = 8000;
client.bind(port);
var message = new Buffer('this is a message');
client.send(message, 0, message.length, 4000, 'localhost', function(error, bytes) {
if (error) {throw error;}
client.close();
});
// Datagram Multicast Server
// Message multicasting can be useful when you don’t need to know the address of all peers. Peers just have to "tune in" and listen to that channel.
// For instance, you could have an event logging server listening on multiple "channels".
// When another process needs to log in to a "channel", it would multicast a message containing the event details into that "channel".
// Nodes can report their interest in listening to certain multicast channels by
// tuning in to that channel. In IP addressing, a space is reserved for multicast addresses.
// In IPv4 the range is between 224.0.0.0 and 239.255.255.255, but some of these are reserved.
// ./udp_client.js 230.1.2.3 4000
var server = require('dgram').createSocket('udp4');
server.on('message', function(message, rinfo) {
console.log('server got message: ' + message + ' from ' + rinfo.address + ':' + rinfo.port);
});
server.bind(4000);
server.addMembership('230.1.2.3');
// Tells the kernel that this UDP socket should receive multicast messages for the multicast address 230.1.2.3.
// Sending Multicast Messages
var dgram = require('dgram');
var client = dgram.createSocket('udp4');
var message = new Buffer('this is a multicast message');
client.bind(4000);
client.setMulticastTTL(10); // Set the multicast time-to-live (TTL) to 10.
// This TTL tells the network how many hops (routers) the datagram can travel through before it is discarded.
// Every time a UDP packet travels through a hop, the TTL counter is decremented, and if 0 is reached, the packet is discarded.
client.send(message, 0, message.length, 4000, '230.1.2.3');
client.close();
// TLS SSL Server
var tls = require('tls');
var fs = require('fs');
var serverOptions = {
key: fs.readFileSync('./my_key.pem'),
cert: fs.readFileSync('./my_certificate.pem'),
ca: [fs.readFileSync('fake_ca.pem')],
requestCert: true, // asks the client to send over the certificate
rejectUnauthorized: true // reject certificates that are not validated by the Certificate Authority chain
};
var server = tls.createServer(serverOptions);
server.on('secureConnection', function (clientStream) {
console.log('got a new connection');
console.log('client authorized:', clientStream.authorized);
clientStream.on('data', function (data) {
console.log('got some data from the client:', data);
clientStream.write('Hey Hello Client!');
if (data.toString().trim().toLowerCase() === 'quit') {
clientStream.end('Bye bye!');
}
});
});
server.listen(4001);
// TLS SSL Client
var tls = require('tls');
var fs = require('fs');
var options = {
key: fs.readFileSync('/path/to/my/private_key.pem'),
cert: fs.readFileSync('/path/to/my/certificate.pem')
};
var client = tls.connect(4001, '127.0.0.1', options, function() {
console.log('connected');
console.log('authorized: ' + client.authorized);
if (! client.authorized) {
console.log('client denied access:', client.authorizationError);
} else {
// ...
}
client.on('data', function (data) {
console.log('got some data from the server:', data);
client.write('Hey, hello Server!');
client.end('Bye bye!');
});
});
// TLS chat server
var tls = require('tls');
var fs = require('fs');
var port = 4001;
var clients = [];
var options = {
key: fs.readFileSync('server_key.pem'),
cert: fs.readFileSync('server_cert.pem')
};
var server = tls.createServer(options, function(client) {
clients.push(client);
client.on('data', function(data) {
var socket = client.socket;
clients.forEach(function(clientFromArray) {
if (clientFromArray !== client) {
clientFromArray.write(socket.remoteAddress + ':' + socket.remotePort + ' said: ' + data);
}
});
});
client.on('close', function() {
console.log('closed connection');
clients.splice(clients.indexOf(client), 1);
});
});
server.listen(port, function() {
console.log('listening on port', server.address().port);
});
// HTTPS Server
var fs = require('fs');
var https = require('https');
var options = {
key: fs.readFileSync('server_key.pem'),
cert: fs.readFileSync('server_cert.pem'),
requestCert: true, // asks the client to send over the certificate
rejectUnauthorized: true // reject certificates that are not validated by the Certificate Authority chain
};
var server = https.createServer(options, function(request, response) {
console.log('authorized:', request.socket.authorized);
console.log('client certificate:', request.socket.getPeerCertificate());
response.writeHead(200, {'Content-Type': 'text/plain'});
response.end('Hello World!');
});
server.listen(4001, '192.168.1.100', function() {
console.log('Server is listening now on port', server.address().port);
});
// HTTPS Client
var fs = require('fs');
var https = require('https');
var options = {
host: '0.0.0.0',
port: 4001,
method: 'GET',
path: '/'
};
var request = https.request(options, function (response) {
console.log('response statusCode:', response.statusCode);
console.log('server authorized:', response.socket.authorized);
console.log('server certificate: ' + response.socket.getPeerCertificate());
response.on('data', function (data) {
console.log('got some data back from the server:', data);
});
});
request.write('Hey!');
request.end();
// WebSocket Server
var ioserver = require('socket.io')
ioserver.sockets.on('connection', function (socket) {
socket.on('my event', function (content) {
console.log(content);
});
socket.on('clientMessage', function(content) {
socket.emit('serverMessage', 'You said: ' + content);
socket.get('username', function(err, username) {
if (! username) {username = socket.id;}
socket.get('room', function(error, room) {
if (error) {throw error;}
var broadcast = socket.broadcast;
var message = content;
if (room) {
broadcast.to(room);
}
broadcast.emit('serverMessage', username + ' said: ' + message);
});
});
});
socket.on('join', function(room) {
socket.get('room', function(err, oldRoom) {
if (error) {throw error;}
socket.set('room', room, function(error) {
if (error) {throw error;}
socket.join(room);
if (oldRoom) {socket.leave(oldRoom);}
socket.get('username', function(err, username) {
if (! username) {username = socket.id;}
});
socket.emit('serverMessage', 'You joined room ' + room);
socket.get('username', function(err, username) {
if (! username) {username = socket.id;}
socket.broadcast.to(room).emit('serverMessage', 'User ' + username + ' joined this room');
});
});
});
});
socket.on('disconnect', function() {
socket.get('username', function(err, username) {
if (! username) {username = socket.id;}
socket.broadcast.emit('serverMessage', 'User ' + username + ' disconnected');
});
});
socket.on('login', function(username) {
socket.set('username', username, function (error) {
if (error) {throw error;}
socket.emit('serverMessage', 'Currently logged in as ' + username);
socket.broadcast.emit('serverMessage', 'User ' + username + ' logged in');
});
});
socket.emit('login');
});
ioserver.listen(4000);
// Websocket Client
<html>
<head>
<title>Socket.IO example application</title>
<script src="http://localhost:4000/socket.io/socket.io.js"></script>
<script>
var socket = io.connect('http://localhost:4000');
socket.on('serverMessage', function(content) {
console.log(content);
});
socket.on('login', function() {
var username = prompt('What username would you like to use?');
socket.emit('login', username);
});
socket.emit('my event', 'Hello world.');
</script>
</head>
<body></body>
</html>
// WebSocket Server with Standart Server
var fs = require('fs');
var http = require('http');
var ioserver = require('socket.io');
var server = http.createServer();
server.on('request', function (request, response) {
fs.readFile(__dirname + '/index.html', function(error, data) {
if (error) {
res.writeHead(500);
res.end('Error loading index.html');
} else {
res.writeHead(200, 'OK');
res.end(data);
}
});
});
ioserver.sockets.on('connection', function (socket) {
socket.on('my event', function(content) {
console.log(content);
});
socket.on('clientMessage', function (content) {
socket.emit('serverMessage', 'You said: ' + content);
socket.get('username', function(err, username) {
if (! username) {username = socket.id;}
socket.broadcast.emit('serverMessage', username + ' said: ' + content);
});
});
socket.on('disconnect', function() {
socket.get('username', function(err, username) {
if (! username) {username = socket.id;}
socket.broadcast.emit('serverMessage', 'User ' + username + ' disconnected');
});
});
socket.on('login', function(username) {
socket.set('username', username, function (error) {
if (error) {throw error;}
socket.emit('serverMessage', 'Currently logged in as ' + username);
socket.broadcast.emit('serverMessage', 'User ' + username + ' logged in');
});
});
socket.emit('login');
});
server.listen(4000);
ioserver.listen(4000);
// Path
path.normalize('/foo//bar//baz/asdf/quux/..'); // '/foo/bar/baz/asdf'
path.join('/foo', 'bar', 'baz/asdf'); // '/foo/bar/baz/asdf'
path.resolve('/foo/bar', '../baz'); // 'C:\foo\baz'
path.relative('/data/test/aaa', '/data/impl/bbb'); // '../bbb'
path.dirname('/foo/bar/baz/asdf/quux.txt'); // '/foo/bar/baz/asdf'
path.basename('/foo/bar/baz/asdf/quux.html'); // 'quux.html'
// Files
fs.exists('/does_not_exist', function (exists) {
console.log('exists:', exists);
});
fs.stat('/etc/passwd', function(err, stats) {
console.log(stats.isFile());
console.log(stats.isDirectory());
console.log(stats.isBlockDevice());
console.log(stats.isCharacterDevice());
console.log(stats.isSymbolicLink());
console.log(stats.isFifo());
console.log(stats.isSocket());
});
fs.open('./my_file.txt', 'r', function opened(err, fd) {
if (err) { throw err }
var readBuffer = new Buffer(1024),
bufferOffset = 0,
bufferLength = readBuffer.length,
filePosition = 100;
fs.read(fd, readBuffer, bufferOffset, bufferLength, filePosition, function read (err, readBytes) {
if (err) { throw err; }
console.log('just read ' + readBytes + ' bytes');
if (readBytes > 0) {console.log(readBuffer.slice(0, readBytes));}
fs.close(fd);
});
});
fs.open('./my_file.txt', 'a', function opened(err, fd) {
if (err) { throw err; }
var writeBuffer = new Buffer('writing this string'),
bufferPosition = 0,
bufferLength = writeBuffer.length, filePosition = null;
fs.write(fd, writeBuffer, bufferPosition, bufferLength, filePosition, function wrote(err, written) {
if (err) { throw err; }
console.log('wrote ' + written + ' bytes');
fs.close(fd);
});
});
// Streams
fs.open(path, 'r', function(err, fd) {
fs.createReadStream(null, {fd: fd, encoding: 'utf8'});
fd.on('data', function (chunk) {console.log(chunk);});
});
require('http').createServer(function(req, res) {
var rs = fs.createReadStream('/path/to/big/file');
rs.on('data', function(data) {
var sent = res.write(data);
if (!sent) {
rs.pause();
}
});
res.on('drain', function() {
rs.resume();
});
rs.on('end', function() {
res.end();
});
}).listen(8080);
require('http').createServer(function(req, res) {
var rs = fs.createReadStream('/path/to/big/file');
rs.pipe(res, {end: false});
rs.on('end', function() {
res.write("And that's all, folks!");
res.end();
});
}).listen(8080);
require('http').createServer(function(req, res) {
var rs = fs.createReadStream('/path/to/big/file');
rs.pipe(res);
}).listen(8080);
// Process Swarm
node plus_one.js
// unpause the stdin stream
process.stdin.resume();
process.stdin.on('data', function( data) {
var number;
try {
number = parseInt(data.toString(), 10); // parse the input data into a number
number += 1; // increment by one
process.stdout.write(number + "\n"); // output the number
} catch (err) {
process.stderr.write(err.message + "\n");
}
});
node plus_one_test.js
var spawn = require('child_process').spawn;
var child = spawn('node', ['plus_one.js']); // Spawn the child with a node process executing the plus_one app
setInterval(function () { // Call this function every 1 second (1000 milliseconds):
var number = Math.floor(Math.random() * 10000); // Create a random number smaller than 10.000
child.stdin.write(number + "\n"); // Send that number to the child process:
child.stdout.once('data', function (data) { // Get the response from the child process and print it:
console.log('child replied to ' + number + ' with: ' + data);
}); // Because you want to listen for data back from the child only once per number, you will use child.stdout.once and not child.stdout.on.
// If you used the latter function, you would register multiple callback functions as time went by.
// Each callback function would be called every time you got data from on the child stdout, which would end up printing the data multiple times and erroneously.
}, 1000);
child.stderr.on('data', function(data) {
process.stdout.write(data);
});
child.on('exit', function(code, signal) {
if (code) {
console.log('child process terminated with code ' + code);
} else if (signal) {
console.log('child process terminated because of signal ' + signal);
}
});
setTimeout(function() {
child.kill();
}, 5000);
var spawn = require('child_process').spawn;
require('http').createServer(function(request, response) {
var child = spawn('tail', ['-f', '/var/log/system.log']);
child.stdout.pipe(res);
res.on('end', function() {
child.kill();
});
}).listen(4000);
// Uncaught Exception
process.on('uncaughtException', function(err) {
// do something
});
// MySQL
// npm install mysql
var mysql = require('mysql');
var client = mysql.createClient({
host: 'localhost',
user: 'root',
password: 'root',
});
client.query('DROP DATABASE IF EXISTS node');
client.query('CREATE DATABASE node');
client.query('USE node');
client.query('CREATE TABLE test ' +
'(id INT(11) AUTO_INCREMENT, ' +
' content VARCHAR(255), ' +
' PRIMARY KEY(id))'
);
for (var i = 0; i < 10000; i++) {
client.query('INSERT INTO test (content) VALUES (?)', ['content for row ' + (i + 1)]);
}
client.query('UPDATE test SET content = ? WHERE id >= ?', ['new content', 9000], function (err, info) {
console.log('Changed content of ' + info.affectedRows + ' rows');
});
query = client.query('SELECT id, content FROM test WHERE id >= ? AND id <= ?', [8990, 9010]);
query.on('error', function(err) {throw err;});
query.on('row', function(row) {console.log('Content of row #' + row.id + ' is: "' + row.content + '"');});
query.on('end', function(result) {console.log('Finished retrieving results');});
client.end();
четверг, 29 июня 2017 г.
JavaScript - Convert Seconds to Days : Hours : Minutes : Seconds
var totalSeconds = 1 * 60 * 60 * 24 * 2 + 1 + 60 + 60 * 60 * 5;
var days = Math.floor(totalSeconds / 86400);
totalSeconds %= 86400;
var hours = Math.floor(totalSeconds / 3600);
totalSeconds %= 3600;
var minutes = Math.floor(totalSeconds / 60);
var seconds = totalSeconds % 60;
console.log(days + ' ' + hours + ':' + minutes + ':' + seconds);
var days = Math.floor(totalSeconds / 86400);
totalSeconds %= 86400;
var hours = Math.floor(totalSeconds / 3600);
totalSeconds %= 3600;
var minutes = Math.floor(totalSeconds / 60);
var seconds = totalSeconds % 60;
console.log(days + ' ' + hours + ':' + minutes + ':' + seconds);
среда, 28 июня 2017 г.
Webpack 2 и 3 API
------------------------------------------------------------------------
Webpack 2 API
------------------------------------------------------------------------
Комментарии
Файлы с модулями ищутся во всех директориях, перечисленных в массиве resolve.modules = []
С помощью объекта resolve.alias = {} можно указать альтернативный путь к файлу модуля, которые заменит его путь, указанный в импорте.
Если путь к файлу модулю указанный в импорте имеет расширение файла, то загружается сразу.
Если в пути расширение не указано, то проверяется перечень расширений файлов, указанных в массиве resolve.extensions = ['.js', '.jsx']
и загружается файл, соотвествующий первому найденному расширению.
Если путь в импорте указывает на директорию, то в ней ищется файл package.json, внутри которого ищутся пути указанные в resolve.mainFields,
если такой путь найден, то он берется, как путь до файла, в противном случае ищутся пути, указанные в resolve.mainFiles и, если такой путь найден,
то он становится путем до файла. Раширение файла берется из resolve.extensions.
Такой же принцип поиска файлов и у загрузчиков модулей.
module.preLoaders и module.postLoaders были удалены. Взамен их в rules надо указывать свойство enforce: "pre"
Плагин webpack.optimize.DedupePlugin был удален
Плагин BannerPlugin принимает теперь только 1 объект вместо 2-х параметров
Конфиги к лоадерам теперь надо указывать внутри rules:
module: {
rules: [{
test: /\.tsx?$/,
loader: 'ts-loader'
options: {transpileOnly: false} // work with webpack 2
}]
},
// does not work with webpack 2
ts: {transpileOnly: false}
------------------------------------------------------------------------
Запуск сборки через package.json
npm start
"scripts": {
"start": "webpack --progress --watch --config webpack.config.js webpack-dev-server --open"
}
// Dev Server start at http://localhost:8080
------------------------------------------------------------------------
const path = require('path');
const webpack = require('webpack'); // импорт wepack для получения доступа к встроенным в Webpack плагинам
const HtmlWebpackPlugin = require('html-webpack-plugin'); // импорт отдельно установленного плагина для Webpack
------------------------------------------------------------------------
const config = {
------------------------------------------------------------------------
context: path.join(__dirname, 'source'), // Базовая директория - абсолютный путь для поиска исходного главного файла entry и загрузчиков модулей
// Абсолютный путь до папки с файлом указанным в entry. По умолчанию равно process.cwd(). А также исходная точка для поиска загрузчиков модулей module.rules.loader
------------------------------------------------------------------------
entry: './index.js', // Исходный главный файл (string | object | array)
entry: ['./library.js', './index.js'], // Последовательный набор, идущих друг за другом исходных файлов, которые будут объединены в 1 общий фыайл. Последний в списке файл главный и только он экспортируется в output.
entry: { // Несколько разных исходных главных файлов
page1: './index1.js', // Исходный главный файл для страницы 1
page2: ['./library.js', './index2.js'] // Исходный главный файл для страницы 2
},
------------------------------------------------------------------------
output: {
path: path.join(__dirname, '/home/proj/public/dist/[hash]'), // Только абсолютный путь до папки с итоговыми файлами. (string)
publicPath: '/dist/[hash]', // Например "https://cdn.example.com/assets/" - Браузерный путь до папки, где лежат итоговый файлы. Предназначен для использования вместе с Webpack Dev Server. (string)
publicPath: "https://cdn.example.com/assets/", // CDN (always HTTPS)
publicPath: "//cdn.example.com/assets/", // CDN (same protocol)
publicPath: "/assets/", // server-relative
publicPath: "assets/", // relative to HTML page
publicPath: "../assets/", // relative to HTML page
publicPath: "", // relative to HTML page (same directory)
pathinfo: true // Включить в сборку информацию откуда взялся каждый модуль
filename: "[name].bundle.js", // Имя итогового файла (string)
// [id] - идентификатор модуля
// [name] - имя итогового файла
// [hash] - хэш итогового файла
// [chunkhash] - хэш части сборки итогового файла
// [filebase] - базовое имя файла
// [file] - имя файла
// [query] - что-то что следует после ? в имени файла
chunkFilename: "[id].bundle.js", // Имя итоговой части сборки
// [id] - идентификатор части сборки
// [name] - имя части сборки
// [hash] - хэш части сборки
// [chunkhash] - хэш части сборки
sourceMapFilename: "[file].map" // Имя файлов source map, размещаемых в папке output.path
// [file] - имя итогового JavaScript-файла
// [id] - идентификатор части сборки
// [hash] хэш итогового файла
// [contenthash] заменен на hashфайла (в webpack 3.0.0).
sourcePrefix: "\t" // Изменить префикс у каждой линии сборки итогового файла
strictModuleExceptionHandling: false
hashDigest: 'hex' // Используемый алгоритм для создания хэшей [hash]
hashDigestLength: 20 // Длина создаваемых хэшей [hash]
hashFunction: 'md5' // Используемая функция для создания хэшей [hash]
hashSalt: '' // Соль для создания хэшей [hash]
chunkLoadTimeout: 120000 // Число миллисекунд до того, как chunk устареет
library: 'lib.js' // Если задано, то итоговая сборка будет экспортирована как отдельная библиотека с указанным именем. Используется только, если вы хотите собрать отдельную библиотеку. (string)
libraryTarget: "var" // В каком формате написать экспорт содержимого библиотеки? var Library = ...library code...; (string)
libraryExport: '' // Позволяет задать export для библиотеки
umdNamedDefine: true // При указании libraryTarget: "umd" именует модуль UMD сборки
crossOriginLoading: "anonymous" // Включить cross-origin loading для частей сборки
devtoolModuleFilenameTemplate: "webpack:///[resource-path]?[loaders]" // Имя файла шаблона для генерируемых файлов source map
devtoolFallbackModuleFilenameTemplate: "" // Имя файла шаблона когда происходит дублирование
devtoolLineToLine: { // генерировать source map, привязанный линией к линии к исходному файлу Данная опция больше не используется
test: test: /\.js$/, // Регулярное выражение для поиска файлов, для которых будет произведено создание sourve map
exclude: /node_modules/, // Регулярное выражение для поиска файлов, для которых не будет произведено создание sourve map
include: ['/source/file2.js', '/source/file3.js'] // Массив путей до файлов, которые тоже нужно созданить source map
}
hotUpdateChunkFilename: "[id].[hash].hot-update.js" // Имя файла для частей с горячим обновлением, размещаемых в папке output.path
// [id] - идентификатор обновления
// [hash] - хэш обновления
hotUpdateMainFilename: "[hash].hot-update.json" // имя главного файла с горячим обновлением, размещаемиого в папке output.path
// [hash] - хэш сборки
hotUpdateFunction: "webpackHotUpdate" // Имя функци JSONP, используемой Webpack для асинхронной загрузки обновлений частей сборки
jsonpFunction: '' // Используется только если установлена target: 'web' - имя функции для асинхронной загрузки chunks
}
------------------------------------------------------------------------
externals: { // Перечень модулей, которые не должны быть включены в итоговую сборку, а должны быть вынесены в отдельные файлы, которые будут загружаться отдельно через <script>
"lodash": {
commonjs: "lodash",
commonjs2: "lodash",
amd: "lodash",
root: "_"
}
{
a: false, // модуль a не будет вынесен во вне
b: true, // модуль b будет вынесен во вне `module.exports = b`
"./c": "c", // модуль "./c" будет вынесен во вне `module.exports = c`
"./d": "var d", // модуль "./d" будет вынесен во вне `module.exports = ./d` <-- здесь будет синтакическая ошибка
"./f": "commonjs ./a/b", // модуль "./f" будет вынесен во вне `module.exports = require("./a/b")`
"./f": "this ./a/b" // модуль "./f" будет вынесен во вне `(function() { module.exports = this["./a/b"]; }())`
},
/^[a-z\-0-9]+$/, // Каждый модуль не входящий в это выражение будет вынесен во вне abc -> require("abc")
function(context, request, callback) { // Какждый модуль, имеющий в своем имени префикс "global-" будет вынесен во вне "global-abc" -> abc
if(/^global-/.test(request)) {return callback(null, "var " + request.substr(7));}
callback();
},
"./e" // модуль "./e" будет вынесен во вне (require("./e"))
subtract: ['./math', 'subtract']
},
-------------------------------------------
externals: [
'react',
'react-dom'
'library/A',
'library/B',
/^library\/.+$/ // everything that starts with "library/"
]
------------------------------------------------------------------------
module: { // Объект со списком загрузчиков модулей
------------------------------------------------------------------------
-------------------------------------------
// Набор общих опций
exprContextCritical: true,
exprContextRecursive: true,
exprContextRegExp: false,
exprContextRequest: ".",
unknownContextCritical: true,
unknownContextRecursive: true,
unknownContextRegExp: false,
unknownContextRequest: ".",
wrappedContextCritical: false
wrappedContextRecursive: true,
wrappedContextRegExp: /.*/,
strictExportPresence: false // since webpack 2.3.0
------------------------------------------------------------------------
resolveLoader: { // Где искать загрузчики модулей
// Имеет такой же набор опций, что и resolve для файлов, но только для загрузчиков модулей
moduleExtensions: ['-loader'] // Массив расширений загрузчиков модулей
enforceExtension: true // Запретить указывать пути файлов без расширений файлов
modules: [path.join(__dirname, 'src'), 'node_modules'] // Массив имен папок внутри данной директории, в которых надо искать загрузчикимодулей.
enforceModuleExtension: true // Использовать расширения для модулей загрузчиков
alias: { // Заменить имя загрузчика модуля на его полное имя
txt: 'raw-loader'
}
aliasFields: ["browser"] // Указать поле, которое будет обработано парсером
descriptionFiles: ["package.json"] // JSON файлы, которые будут использованы для descriptions
mainFields: ["browser", "module", "main"] // искать пути к модулям в указанных полях файлов package.json: {...main: 'build/d3.Node.js', browser: 'build/d3.js', module: 'index', ...}
mainFiles: ["index"] // Поиск фалов с данными исенами, если вместо пути к файлу указан путь к директории
unsafeCache: true // Включить небезопасное кэширование модулей
cachePredicate: function() { return true } // Функция определяющая стоит ли кэшировать запрос
plugins: [new DirectoryNamedWebpackPlugin()] // Наборе плагинов для поиска файлов модулей
symlinks: true // Искать файлы по ссылкам ярлыкам
}
------------------------------------------------------------------------
resolve: { // Где искать исходные файлы для сборки
extensions: ['.ts', '.js', '.json'] // Массив расширений исходных файлов которые надо включать в сборку
enforceExtension: true // Запретить указывать пути файлов без расширений файлов
modules: [path.join(__dirname, 'src'), 'node_modules'] // Массив имен папок внутри данной директории, в которых надо искать исходные файлы.
enforceModuleExtension: true // Использовать расширения для модулей загрузчиков
alias: { // Заменить имя модуля в импорте на путь до файла
jquery: "jquery/src/jquery"
}
aliasFields: ["browser"] // Указать поле, которое будет обработано парсером
descriptionFiles: ["package.json"] // JSON файлы, которые будут использованы для descriptions
mainFields: ["browser", "module", "main"] // искать пути к модулям в указанных полях файлов package.json: {...main: 'build/d3.Node.js', browser: 'build/d3.js', module: 'index', ...}
mainFiles: ["index"] // Поиск фалов с данными исенами, если вместо пути к файлу указан путь к директории
unsafeCache: true // Включить небезопасное кэширование модулей
cachePredicate: function() { return true } // Функция определяющая стоит ли кэшировать запрос
plugins: [new DirectoryNamedWebpackPlugin()] // Наборе плагинов для поиска файлов модулей
symlinks: true // Искать файлы по ссылкам ярлыкам
},
noParse: [/\.ts$/, /\.tsx$/] // Не парсить перед сборкой файлы, перечисленные в данном массиве. Ожидается, что эти файлы сами ничего не импортирую. В них есть только экспорт exports и module.exports.
rules: [ // Массив загрузчиков модулей загружающие файлы во время сборки итогового файла
// Внимание! Webpack ищет загрузчики модулей относительно файла с конфигом. Если ваши загрузчики установлены в папке node_modules вне в родительской директории,
// то Webpack не сможет их сам найти.
{
test: /\.txt$/, // Какие файлы должен загружать данный загрузчик модулей
use: 'raw-loader' // Какой загрузчик модулей должен загружать данные файлы
// loader: 'raw-loader' // Альтернатива use - Какой загрузчик модулей должен загружать данные файлы
options: { // Набор опций для данного загрузчика модулей
presets: ["es2015"]
},
include: [// Массив путей до файлов, которые тоже нужно загружать данным загрузчиком модулей
path.resolve(__dirname, "app") // Только абсолютные пути
],
exclude: [ // Массив путей до файлов, которые ненужно загружать данным загрузчиком модулей
path.resolve(__dirname, "app/demo-files") // Только абсолютные пути
],
issuer: { test, include, exclude }, // условия дляissuer (the origin of the import)
enforce: "pre" // Загрузчик модулей только для предварительной обработки перед сборкой взамен удаленных module.preLoaders и module.postLoaders
enforce: "post", // Загрузчик модулей только для обработки после сборки взамен удаленных module.preLoaders и module.postLoaders
parser: {
amd: false, // disable AMD
commonjs: false, // disable CommonJS
system: false, // disable SystemJS
harmony: false, // disable ES2015 Harmony import/export
requireInclude: false, // disable require.include
requireEnsure: false, // disable require.ensure
requireContext: false, // disable require.context
browserify: false, // disable special handling of Browserify bundles
requireJs: false, // disable requirejs.*
node: false, // disable __dirname, __filename, module, require.extensions, require.main, etc.
node: {...} // reconfigure node layer on module level
}
}
{
test: /\.css$/, // Регулярное выражение для поиска файлов, загружаемых данным загрузчиком модулей
use: [ // Массив с перечнем модулей загрузчиков, используемых для загрузки данных типов файлов, и выполняющихся с конца в начало
{
loader: 'style-loader' // Имя загрузчика модулей
},
{
loader: 'css-loader', // Имя загрузчика модулей
options: {// Опции для данного загрузчика модулей
modules: true
}
}
]
}
{
test: /\.js$/,
exclude: /(node_modules)/,
use: [{
loader: 'babel-loader',
options: {
presets: [['es2015', {modules: false}]],
plugins: [
'syntax-async-functions',
'syntax-dynamic-import',
'transform-async-to-generator',
'transform-regenerator',
'transform-runtime'
]
}
}]
}
{
resource: /filename/, // matches "/path/filename.js"
resourceQuery: /^\?querystring$/, // matches "?querystring"
issuer: /filename/, // matches "/path/something.js" if requested from "/path/filename.js"
}
]
}
------------------------------------------------------------------------
plugins: [ // Массив плагинов, применяемых к итоговому файлу сборки
new webpack.optimize.UglifyJsPlugin({ // Плагин для минимизации итогового файла сборки
sourceMap: options.devtool && (options.devtool.indexOf("sourcemap") >= 0 || options.devtool.indexOf("source-map") >= 0)
}),
new HtmlWebpackPlugin({template: './src/index.html'}),
new webpack.HotModuleReplacementPlugin() // Включить Hot Module Replacement (HMR)
new webpack.DefinePlugin({'process.env.NODE_ENV': JSON.stringify('production')})
new webpack.optimize.CommonsChunkPlugin({name: ['polyfills', 'vendor'].reverse()}),
new webpack.ProvidePlugin({
$: 'jquery',
jQuery: 'jquery'
__assign: ['tslib', '__assign'],
__extends: ['tslib', '__extends'],
})
function() {
this.plugin("done", function(stats) { // save to file extracted from webpack compilation stats
require("fs").writeFileSync(
path.join(__dirname, "build", "stats.json"),
JSON.stringify(stats.toJson()));
});
}
]
------------------------------------------------------------------------
target: 'web' // Скомпилировать сборку для использования в браузере
------------------------------------------------------------------------
bail: true // Прервать сборку при обнаружении хоть одной ошибки
------------------------------------------------------------------------
profile: true // Получать информацию о времени сборки каждого модуля
------------------------------------------------------------------------
recordsPath: path.join(__dirname, 'records.json') // Записывать в файл информации об изменении сборки каждого модуля между сборками
recordsInputPath: path.join(__dirname, 'records.json'), // из какого файла читать последнюю информацию о сборке
recordsOutputPath: path.join(__dirname, 'newRecords.json') // в какой файл записывать
------------------------------------------------------------------------
cache: true // Кэшировать сборку для ускорения пересборки
------------------------------------------------------------------------
watch: true // Отслеживать изменения файлов и запускать пересборку
------------------------------------------------------------------------
watchOptions: { // Опции для процесса отслеживания изменений файлов для сборки
ignored: "files/**/*.js" // Какие файлы не отслеживать для пересборки
aggregateTimeout: 300, // Задержка перед запуском пересборки на случай если сейчас будут еще изменены файлы
poll: 1000 // С каким интервалом проверять изменения в файлах
}
------------------------------------------------------------------------
devtool: 'inline-source-map' // В каком виде производить сборку source map
------------------------------------------------------------------------
devServer: { // конфиг для webpack-dev-server
hot: true, // Сказать dev-server, что мы испольлзуем Hot Module Replacement (HMR)
lazy: true // Компилирует сборку только при запросе файлов из браузера. Не смотрит на изменения файлов watch
filename: "bundle.js" // используется совместо с lazy: true
contentBase: [path.join(__dirname, "public"), path.join(__dirname, "assets")], // boolean | string | array, место расположения статичных файлов для загрузки
staticOptions: { // Опции для загрузки статичных файлов
redirect: false
}
watchContentBase: true // Остлеживать ли изменения статичных файлов и перезагружать ли после этого страницу браузера
watchOptions: { // Опции для остлеживания процесса изменения файлов для сборки
poll: true
}
https: false, // true для self-signed, объект для cert authority
host: 'localhost', // (работает только в CLI)
port: 7777, // (работает только в CLI)
publicPath: "/assets/" // итоговая сборка будет доступна браузеру по указанному пути
publicPath: "http://localhost:8080/assets/"
allowedHosts: [ // Список разрешенных хостов
'host.com',
'subdomain.host.com',
'subdomain2.host.com',
'host2.com'
]
proxy: { // прокси URL на backend development server
'/api': 'http://localhost:3000'
"/api": {
target: "http://localhost:3000",
pathRewrite: {"^/api" : ""}
}
"/api": {
target: "http://localhost:3000",
bypass: function(req, res, proxyOptions) {
if (req.headers.accept.indexOf("html") !== -1) {
console.log("Skipping proxy for browser request.");
return "/index.html";
}
}
}
},
headers: { // Добавить эти заголовки при ответе браузеру
"X-Custom-Foo": "bar"
}
https: { // Сертификаты для HTTPS
key: fs.readFileSync("/path/to/server.key"),
cert: fs.readFileSync("/path/to/server.crt"),
ca: fs.readFileSync("/path/to/ca.pem"),
}
historyApiFallback: { // true для index.html вплоть 404 или объект для множественных путей
rewrites: [
{ from: /^\/$/, to: '/views/landing.html' },
{ from: /^\/subpage/, to: '/views/subpage.html' },
{ from: /./, to: '/views/404.html' }
]
}
noInfo: true, // только логи errors и warns при hot reload, остальная информация при сборке будет скрыта в консоли командной строки
quiet: true // вся информация о сборке будет скрыта в консоли командной строки
clientLogLevel: "none" //
compress: true, // включить gzip compression
stats: 'minimal', // Какую информацию о сборке выводить в консоль командной строки
hotOnly: true // Включить Hot Module Replacement (работает только в CLI)
inline: false // Включить вставку кода inline или в <iframe> (работает только в CLI)
overlay: { // Показывать сообщения об ошибке сборки прямо на странице браузера, а не в консоли
warnings: true,
errors: true
}
progress: true // Показывать прогрессбар сборки (работает только в CLI)
public: "myapp.test:80" // Указывается при проксирование через Nginx (работает только в CLI)
setup: function (app) { // Собственная функция middleware для Express
app.get('/some/path', function(req, res) {
res.json({ custom: 'response' });
});
}
}
------------------------------------------------------------------------
performance: { // Конфигурирование как отражать информацию о производительности проведения сборки
hints: "warning", // включить или выключить подсказки по производительности
maxAssetSize: 200000, // int (in bytes), - при каких лимитах показывать подсказки по производительности
maxEntrypointSize: 400000, // int (in bytes) - при каких лимитах показывать подсказки по производительности
assetFilter: function (assetFilename) { // Какой файл использовать для оценки производительности сборки
return assetFilename.endsWith('.css') || assetFilename.endsWith('.js');
}
},
------------------------------------------------------------------------
stats: "errors-only", // Какую информацию о сборке показывать на экране консоли
stats: {
// Add asset Information
assets: true,
// Sort assets by a field
assetsSort: "field",
// Add information about cached (not built) modules
cached: true,
// Show cached assets (setting this to `false` only shows emitted files)
cachedAssets: true,
// Add children information
children: true,
// Add chunk information (setting this to `false` allows for a less verbose output)
chunks: true,
// Add built modules information to chunk information
chunkModules: true,
// Add the origins of chunks and chunk merging info
chunkOrigins: true,
// Sort the chunks by a field
chunksSort: "field",
// Context directory for request shortening
context: "../src/",
// `webpack --colors` equivalent
colors: true,
// Display the distance from the entry point for each module
depth: false,
// Display the entry points with the corresponding bundles
entrypoints: false,
// Add errors
errors: true,
// Add details to errors (like resolving log)
errorDetails: true,
// Exclude modules which match one of the given strings or regular expressions
exclude: [],
// Add the hash of the compilation
hash: true,
// Set the maximum number of modules to be shown
maxModules: 15,
// Add built modules information
modules: true,
// Sort the modules by a field
modulesSort: "field",
// Show dependencies and origin of warnings/errors (since webpack 2.5.0)
moduleTrace: true,
// Show performance hint when file size exceeds `performance.maxAssetSize`
performance: true,
// Show the exports of the modules
providedExports: false,
// Add public path information
publicPath: true,
// Add information about the reasons why modules are included
reasons: true,
// Add the source code of modules
source: true,
// Add timing information
timings: true,
// Show which exports of a module are used
usedExports: false,
// Add webpack version information
version: true,
// Add warnings
warnings: true,
// Filter warnings to be shown (since webpack 2.4.0),
// can be a String, Regexp, a function getting the warning and returning a boolean
// or an Array of a combination of the above. First match wins.
warningsFilter: "filter" | /filter/ | ["filter", /filter/] | (warning) => ... return true|false
};
------------------------------------------------------------------------
node: { // Включать ли набор разных полифилов для кода Node.js
console: false,
global: true,
process: true,
__filename: "mock",
__dirname: "mock",
Buffer: true,
setImmediate: true
dns: "mock",
fs: "empty",
path: true,
url: false
}
------------------------------------------------------------------------
amd: { // Установить значения для require.amd и define.amd для:
jQuery: true
}
------------------------------------------------------------------------
loader: '' // Передать собственные значения в контекст модуля загрузчика
-----------------------------------------------------------------------
};
------------------------------------------------------------------------
// Компиляция через команду webpack
module.exports = config;
------------------------------------------------------------------------
или
------------------------------------------------------------------------
// Компиляция через Node.js короткий способ
------------------------------------------------------------------------
// Компиляция через Node.js короткий способ
webpack(config, function (error, stats) {
console.log(error); // => fatal compiler error (rar)
var json = stats.toJson() // => webpack --json
console.log(json.errors); // => array of errors
console.log(json.warnings); // => array of warnings
console.log('Done');
}
);
------------------------------------------------------------------------
или
------------------------------------------------------------------------
// Компиляция через Node.js длинный способ
const compiler = webpack(config);
compiler.run(function(error, stats) {
console.log(stats.hasErrors());
console.log(stats.hasWarnings());
console.log(error); // => fatal compiler error (rar)
var json = stats.toJson({chunks: false, hash: true ...}) // => webpack --json
console.log(json.errors); // => array of errors
console.log(json.warnings); // => array of warnings
console.log(stats.toString({
chunks: false, // Makes the build much quieter
colors: true
}));
console.log('Done');
});
// или
const watchOptions = {
aggregateTimeout: 300, // после внесения любого изменения в файл подождать 300 секунд перед началом сборки. Вдруг еще изменения будут.
poll: true // использовать polling вместо native watchers
// можно передать число для установки polling interval
};
const watcher = compiler.watch(watchOptions, function (error, stats) {
console.log(error); // => fatal compiler error (rar)
var json = stats.toJson() // => webpack --json
console.log(json.errors); // => array of errors
console.log(json.warnings); // => array of warnings
console.log('Done');
}
);
watcher.close(function () {console.log('Watcher stoped ');}); // Остановка отслеживания изменений в файлах
------------------------------------------------------------------------
// Полный контроль и запуск Dev Server через Express
------------------------------------------------------------------------
var express = require("express");
var webpackDevMiddleware = require("webpack-dev-middleware");
var webpack = require("webpack");
var webpackConfig = require("./webpack.config");
var app = express();
var compiler = webpack(webpackConfig);
app.use(webpackDevMiddleware(compiler, {
publicPath: "/", // Same as "output.publicPath" in most cases.
filename: "bundle.js", // Same as "output.filename" in most cases.
lazy: true // lazy mode will only recompile on a request to the entry point.
}));
app.listen(3000, function () {
console.log("Listening on port 3000!");
console.log("Depending on what you've used in output.publicPath and output.filename, your bundle now available on http://localhost:3000/bundle.js");
});
Webpack 2 API
------------------------------------------------------------------------
Комментарии
Файлы с модулями ищутся во всех директориях, перечисленных в массиве resolve.modules = []
С помощью объекта resolve.alias = {} можно указать альтернативный путь к файлу модуля, которые заменит его путь, указанный в импорте.
Если путь к файлу модулю указанный в импорте имеет расширение файла, то загружается сразу.
Если в пути расширение не указано, то проверяется перечень расширений файлов, указанных в массиве resolve.extensions = ['.js', '.jsx']
и загружается файл, соотвествующий первому найденному расширению.
Если путь в импорте указывает на директорию, то в ней ищется файл package.json, внутри которого ищутся пути указанные в resolve.mainFields,
если такой путь найден, то он берется, как путь до файла, в противном случае ищутся пути, указанные в resolve.mainFiles и, если такой путь найден,
то он становится путем до файла. Раширение файла берется из resolve.extensions.
Такой же принцип поиска файлов и у загрузчиков модулей.
module.preLoaders и module.postLoaders были удалены. Взамен их в rules надо указывать свойство enforce: "pre"
Плагин webpack.optimize.DedupePlugin был удален
Плагин BannerPlugin принимает теперь только 1 объект вместо 2-х параметров
Конфиги к лоадерам теперь надо указывать внутри rules:
module: {
rules: [{
test: /\.tsx?$/,
loader: 'ts-loader'
options: {transpileOnly: false} // work with webpack 2
}]
},
// does not work with webpack 2
ts: {transpileOnly: false}
------------------------------------------------------------------------
Запуск сборки через package.json
npm start
"scripts": {
"start": "webpack --progress --watch --config webpack.config.js webpack-dev-server --open"
}
// Dev Server start at http://localhost:8080
------------------------------------------------------------------------
const path = require('path');
const webpack = require('webpack'); // импорт wepack для получения доступа к встроенным в Webpack плагинам
const HtmlWebpackPlugin = require('html-webpack-plugin'); // импорт отдельно установленного плагина для Webpack
------------------------------------------------------------------------
const config = {
------------------------------------------------------------------------
context: path.join(__dirname, 'source'), // Базовая директория - абсолютный путь для поиска исходного главного файла entry и загрузчиков модулей
// Абсолютный путь до папки с файлом указанным в entry. По умолчанию равно process.cwd(). А также исходная точка для поиска загрузчиков модулей module.rules.loader
------------------------------------------------------------------------
entry: './index.js', // Исходный главный файл (string | object | array)
entry: ['./library.js', './index.js'], // Последовательный набор, идущих друг за другом исходных файлов, которые будут объединены в 1 общий фыайл. Последний в списке файл главный и только он экспортируется в output.
entry: { // Несколько разных исходных главных файлов
page1: './index1.js', // Исходный главный файл для страницы 1
page2: ['./library.js', './index2.js'] // Исходный главный файл для страницы 2
},
------------------------------------------------------------------------
output: {
path: path.join(__dirname, '/home/proj/public/dist/[hash]'), // Только абсолютный путь до папки с итоговыми файлами. (string)
publicPath: '/dist/[hash]', // Например "https://cdn.example.com/assets/" - Браузерный путь до папки, где лежат итоговый файлы. Предназначен для использования вместе с Webpack Dev Server. (string)
publicPath: "https://cdn.example.com/assets/", // CDN (always HTTPS)
publicPath: "//cdn.example.com/assets/", // CDN (same protocol)
publicPath: "/assets/", // server-relative
publicPath: "assets/", // relative to HTML page
publicPath: "../assets/", // relative to HTML page
publicPath: "", // relative to HTML page (same directory)
pathinfo: true // Включить в сборку информацию откуда взялся каждый модуль
filename: "[name].bundle.js", // Имя итогового файла (string)
// [id] - идентификатор модуля
// [name] - имя итогового файла
// [hash] - хэш итогового файла
// [chunkhash] - хэш части сборки итогового файла
// [filebase] - базовое имя файла
// [file] - имя файла
// [query] - что-то что следует после ? в имени файла
chunkFilename: "[id].bundle.js", // Имя итоговой части сборки
// [id] - идентификатор части сборки
// [name] - имя части сборки
// [hash] - хэш части сборки
// [chunkhash] - хэш части сборки
sourceMapFilename: "[file].map" // Имя файлов source map, размещаемых в папке output.path
// [file] - имя итогового JavaScript-файла
// [id] - идентификатор части сборки
// [hash] хэш итогового файла
// [contenthash] заменен на hashфайла (в webpack 3.0.0).
sourcePrefix: "\t" // Изменить префикс у каждой линии сборки итогового файла
strictModuleExceptionHandling: false
hashDigest: 'hex' // Используемый алгоритм для создания хэшей [hash]
hashDigestLength: 20 // Длина создаваемых хэшей [hash]
hashFunction: 'md5' // Используемая функция для создания хэшей [hash]
hashSalt: '' // Соль для создания хэшей [hash]
chunkLoadTimeout: 120000 // Число миллисекунд до того, как chunk устареет
library: 'lib.js' // Если задано, то итоговая сборка будет экспортирована как отдельная библиотека с указанным именем. Используется только, если вы хотите собрать отдельную библиотеку. (string)
libraryTarget: "var" // В каком формате написать экспорт содержимого библиотеки? var Library = ...library code...; (string)
libraryExport: '' // Позволяет задать export для библиотеки
umdNamedDefine: true // При указании libraryTarget: "umd" именует модуль UMD сборки
crossOriginLoading: "anonymous" // Включить cross-origin loading для частей сборки
devtoolModuleFilenameTemplate: "webpack:///[resource-path]?[loaders]" // Имя файла шаблона для генерируемых файлов source map
devtoolFallbackModuleFilenameTemplate: "" // Имя файла шаблона когда происходит дублирование
devtoolLineToLine: { // генерировать source map, привязанный линией к линии к исходному файлу Данная опция больше не используется
test: test: /\.js$/, // Регулярное выражение для поиска файлов, для которых будет произведено создание sourve map
exclude: /node_modules/, // Регулярное выражение для поиска файлов, для которых не будет произведено создание sourve map
include: ['/source/file2.js', '/source/file3.js'] // Массив путей до файлов, которые тоже нужно созданить source map
}
hotUpdateChunkFilename: "[id].[hash].hot-update.js" // Имя файла для частей с горячим обновлением, размещаемых в папке output.path
// [id] - идентификатор обновления
// [hash] - хэш обновления
hotUpdateMainFilename: "[hash].hot-update.json" // имя главного файла с горячим обновлением, размещаемиого в папке output.path
// [hash] - хэш сборки
hotUpdateFunction: "webpackHotUpdate" // Имя функци JSONP, используемой Webpack для асинхронной загрузки обновлений частей сборки
jsonpFunction: '' // Используется только если установлена target: 'web' - имя функции для асинхронной загрузки chunks
}
------------------------------------------------------------------------
externals: { // Перечень модулей, которые не должны быть включены в итоговую сборку, а должны быть вынесены в отдельные файлы, которые будут загружаться отдельно через <script>
"lodash": {
commonjs: "lodash",
commonjs2: "lodash",
amd: "lodash",
root: "_"
}
{
a: false, // модуль a не будет вынесен во вне
b: true, // модуль b будет вынесен во вне `module.exports = b`
"./c": "c", // модуль "./c" будет вынесен во вне `module.exports = c`
"./d": "var d", // модуль "./d" будет вынесен во вне `module.exports = ./d` <-- здесь будет синтакическая ошибка
"./f": "commonjs ./a/b", // модуль "./f" будет вынесен во вне `module.exports = require("./a/b")`
"./f": "this ./a/b" // модуль "./f" будет вынесен во вне `(function() { module.exports = this["./a/b"]; }())`
},
/^[a-z\-0-9]+$/, // Каждый модуль не входящий в это выражение будет вынесен во вне abc -> require("abc")
function(context, request, callback) { // Какждый модуль, имеющий в своем имени префикс "global-" будет вынесен во вне "global-abc" -> abc
if(/^global-/.test(request)) {return callback(null, "var " + request.substr(7));}
callback();
},
"./e" // модуль "./e" будет вынесен во вне (require("./e"))
subtract: ['./math', 'subtract']
},
-------------------------------------------
externals: [
'react',
'react-dom'
'library/A',
'library/B',
/^library\/.+$/ // everything that starts with "library/"
]
------------------------------------------------------------------------
module: { // Объект со списком загрузчиков модулей
------------------------------------------------------------------------
-------------------------------------------
// Набор общих опций
exprContextCritical: true,
exprContextRecursive: true,
exprContextRegExp: false,
exprContextRequest: ".",
unknownContextCritical: true,
unknownContextRecursive: true,
unknownContextRegExp: false,
unknownContextRequest: ".",
wrappedContextCritical: false
wrappedContextRecursive: true,
wrappedContextRegExp: /.*/,
strictExportPresence: false // since webpack 2.3.0
------------------------------------------------------------------------
resolveLoader: { // Где искать загрузчики модулей
// Имеет такой же набор опций, что и resolve для файлов, но только для загрузчиков модулей
moduleExtensions: ['-loader'] // Массив расширений загрузчиков модулей
enforceExtension: true // Запретить указывать пути файлов без расширений файлов
modules: [path.join(__dirname, 'src'), 'node_modules'] // Массив имен папок внутри данной директории, в которых надо искать загрузчикимодулей.
enforceModuleExtension: true // Использовать расширения для модулей загрузчиков
alias: { // Заменить имя загрузчика модуля на его полное имя
txt: 'raw-loader'
}
aliasFields: ["browser"] // Указать поле, которое будет обработано парсером
descriptionFiles: ["package.json"] // JSON файлы, которые будут использованы для descriptions
mainFields: ["browser", "module", "main"] // искать пути к модулям в указанных полях файлов package.json: {...main: 'build/d3.Node.js', browser: 'build/d3.js', module: 'index', ...}
mainFiles: ["index"] // Поиск фалов с данными исенами, если вместо пути к файлу указан путь к директории
unsafeCache: true // Включить небезопасное кэширование модулей
cachePredicate: function() { return true } // Функция определяющая стоит ли кэшировать запрос
plugins: [new DirectoryNamedWebpackPlugin()] // Наборе плагинов для поиска файлов модулей
symlinks: true // Искать файлы по ссылкам ярлыкам
}
------------------------------------------------------------------------
resolve: { // Где искать исходные файлы для сборки
extensions: ['.ts', '.js', '.json'] // Массив расширений исходных файлов которые надо включать в сборку
enforceExtension: true // Запретить указывать пути файлов без расширений файлов
modules: [path.join(__dirname, 'src'), 'node_modules'] // Массив имен папок внутри данной директории, в которых надо искать исходные файлы.
enforceModuleExtension: true // Использовать расширения для модулей загрузчиков
alias: { // Заменить имя модуля в импорте на путь до файла
jquery: "jquery/src/jquery"
}
aliasFields: ["browser"] // Указать поле, которое будет обработано парсером
descriptionFiles: ["package.json"] // JSON файлы, которые будут использованы для descriptions
mainFields: ["browser", "module", "main"] // искать пути к модулям в указанных полях файлов package.json: {...main: 'build/d3.Node.js', browser: 'build/d3.js', module: 'index', ...}
mainFiles: ["index"] // Поиск фалов с данными исенами, если вместо пути к файлу указан путь к директории
unsafeCache: true // Включить небезопасное кэширование модулей
cachePredicate: function() { return true } // Функция определяющая стоит ли кэшировать запрос
plugins: [new DirectoryNamedWebpackPlugin()] // Наборе плагинов для поиска файлов модулей
symlinks: true // Искать файлы по ссылкам ярлыкам
},
noParse: [/\.ts$/, /\.tsx$/] // Не парсить перед сборкой файлы, перечисленные в данном массиве. Ожидается, что эти файлы сами ничего не импортирую. В них есть только экспорт exports и module.exports.
rules: [ // Массив загрузчиков модулей загружающие файлы во время сборки итогового файла
// Внимание! Webpack ищет загрузчики модулей относительно файла с конфигом. Если ваши загрузчики установлены в папке node_modules вне в родительской директории,
// то Webpack не сможет их сам найти.
{
test: /\.txt$/, // Какие файлы должен загружать данный загрузчик модулей
use: 'raw-loader' // Какой загрузчик модулей должен загружать данные файлы
// loader: 'raw-loader' // Альтернатива use - Какой загрузчик модулей должен загружать данные файлы
options: { // Набор опций для данного загрузчика модулей
presets: ["es2015"]
},
include: [// Массив путей до файлов, которые тоже нужно загружать данным загрузчиком модулей
path.resolve(__dirname, "app") // Только абсолютные пути
],
exclude: [ // Массив путей до файлов, которые ненужно загружать данным загрузчиком модулей
path.resolve(__dirname, "app/demo-files") // Только абсолютные пути
],
issuer: { test, include, exclude }, // условия дляissuer (the origin of the import)
enforce: "pre" // Загрузчик модулей только для предварительной обработки перед сборкой взамен удаленных module.preLoaders и module.postLoaders
enforce: "post", // Загрузчик модулей только для обработки после сборки взамен удаленных module.preLoaders и module.postLoaders
parser: {
amd: false, // disable AMD
commonjs: false, // disable CommonJS
system: false, // disable SystemJS
harmony: false, // disable ES2015 Harmony import/export
requireInclude: false, // disable require.include
requireEnsure: false, // disable require.ensure
requireContext: false, // disable require.context
browserify: false, // disable special handling of Browserify bundles
requireJs: false, // disable requirejs.*
node: false, // disable __dirname, __filename, module, require.extensions, require.main, etc.
node: {...} // reconfigure node layer on module level
}
}
{
test: /\.css$/, // Регулярное выражение для поиска файлов, загружаемых данным загрузчиком модулей
use: [ // Массив с перечнем модулей загрузчиков, используемых для загрузки данных типов файлов, и выполняющихся с конца в начало
{
loader: 'style-loader' // Имя загрузчика модулей
},
{
loader: 'css-loader', // Имя загрузчика модулей
options: {// Опции для данного загрузчика модулей
modules: true
}
}
]
}
{
test: /\.js$/,
exclude: /(node_modules)/,
use: [{
loader: 'babel-loader',
options: {
presets: [['es2015', {modules: false}]],
plugins: [
'syntax-async-functions',
'syntax-dynamic-import',
'transform-async-to-generator',
'transform-regenerator',
'transform-runtime'
]
}
}]
}
{
resource: /filename/, // matches "/path/filename.js"
resourceQuery: /^\?querystring$/, // matches "?querystring"
issuer: /filename/, // matches "/path/something.js" if requested from "/path/filename.js"
}
]
}
------------------------------------------------------------------------
plugins: [ // Массив плагинов, применяемых к итоговому файлу сборки
new webpack.optimize.UglifyJsPlugin({ // Плагин для минимизации итогового файла сборки
sourceMap: options.devtool && (options.devtool.indexOf("sourcemap") >= 0 || options.devtool.indexOf("source-map") >= 0)
}),
new HtmlWebpackPlugin({template: './src/index.html'}),
new webpack.HotModuleReplacementPlugin() // Включить Hot Module Replacement (HMR)
new webpack.DefinePlugin({'process.env.NODE_ENV': JSON.stringify('production')})
new webpack.optimize.CommonsChunkPlugin({name: ['polyfills', 'vendor'].reverse()}),
new webpack.ProvidePlugin({
$: 'jquery',
jQuery: 'jquery'
__assign: ['tslib', '__assign'],
__extends: ['tslib', '__extends'],
})
function() {
this.plugin("done", function(stats) { // save to file extracted from webpack compilation stats
require("fs").writeFileSync(
path.join(__dirname, "build", "stats.json"),
JSON.stringify(stats.toJson()));
});
}
]
------------------------------------------------------------------------
target: 'web' // Скомпилировать сборку для использования в браузере
------------------------------------------------------------------------
bail: true // Прервать сборку при обнаружении хоть одной ошибки
------------------------------------------------------------------------
profile: true // Получать информацию о времени сборки каждого модуля
------------------------------------------------------------------------
recordsPath: path.join(__dirname, 'records.json') // Записывать в файл информации об изменении сборки каждого модуля между сборками
recordsInputPath: path.join(__dirname, 'records.json'), // из какого файла читать последнюю информацию о сборке
recordsOutputPath: path.join(__dirname, 'newRecords.json') // в какой файл записывать
------------------------------------------------------------------------
cache: true // Кэшировать сборку для ускорения пересборки
------------------------------------------------------------------------
watch: true // Отслеживать изменения файлов и запускать пересборку
------------------------------------------------------------------------
watchOptions: { // Опции для процесса отслеживания изменений файлов для сборки
ignored: "files/**/*.js" // Какие файлы не отслеживать для пересборки
aggregateTimeout: 300, // Задержка перед запуском пересборки на случай если сейчас будут еще изменены файлы
poll: 1000 // С каким интервалом проверять изменения в файлах
}
------------------------------------------------------------------------
devtool: 'inline-source-map' // В каком виде производить сборку source map
------------------------------------------------------------------------
devServer: { // конфиг для webpack-dev-server
hot: true, // Сказать dev-server, что мы испольлзуем Hot Module Replacement (HMR)
lazy: true // Компилирует сборку только при запросе файлов из браузера. Не смотрит на изменения файлов watch
filename: "bundle.js" // используется совместо с lazy: true
contentBase: [path.join(__dirname, "public"), path.join(__dirname, "assets")], // boolean | string | array, место расположения статичных файлов для загрузки
staticOptions: { // Опции для загрузки статичных файлов
redirect: false
}
watchContentBase: true // Остлеживать ли изменения статичных файлов и перезагружать ли после этого страницу браузера
watchOptions: { // Опции для остлеживания процесса изменения файлов для сборки
poll: true
}
https: false, // true для self-signed, объект для cert authority
host: 'localhost', // (работает только в CLI)
port: 7777, // (работает только в CLI)
publicPath: "/assets/" // итоговая сборка будет доступна браузеру по указанному пути
publicPath: "http://localhost:8080/assets/"
allowedHosts: [ // Список разрешенных хостов
'host.com',
'subdomain.host.com',
'subdomain2.host.com',
'host2.com'
]
proxy: { // прокси URL на backend development server
'/api': 'http://localhost:3000'
"/api": {
target: "http://localhost:3000",
pathRewrite: {"^/api" : ""}
}
"/api": {
target: "http://localhost:3000",
bypass: function(req, res, proxyOptions) {
if (req.headers.accept.indexOf("html") !== -1) {
console.log("Skipping proxy for browser request.");
return "/index.html";
}
}
}
},
headers: { // Добавить эти заголовки при ответе браузеру
"X-Custom-Foo": "bar"
}
https: { // Сертификаты для HTTPS
key: fs.readFileSync("/path/to/server.key"),
cert: fs.readFileSync("/path/to/server.crt"),
ca: fs.readFileSync("/path/to/ca.pem"),
}
historyApiFallback: { // true для index.html вплоть 404 или объект для множественных путей
rewrites: [
{ from: /^\/$/, to: '/views/landing.html' },
{ from: /^\/subpage/, to: '/views/subpage.html' },
{ from: /./, to: '/views/404.html' }
]
}
noInfo: true, // только логи errors и warns при hot reload, остальная информация при сборке будет скрыта в консоли командной строки
quiet: true // вся информация о сборке будет скрыта в консоли командной строки
clientLogLevel: "none" //
compress: true, // включить gzip compression
stats: 'minimal', // Какую информацию о сборке выводить в консоль командной строки
hotOnly: true // Включить Hot Module Replacement (работает только в CLI)
inline: false // Включить вставку кода inline или в <iframe> (работает только в CLI)
overlay: { // Показывать сообщения об ошибке сборки прямо на странице браузера, а не в консоли
warnings: true,
errors: true
}
progress: true // Показывать прогрессбар сборки (работает только в CLI)
public: "myapp.test:80" // Указывается при проксирование через Nginx (работает только в CLI)
setup: function (app) { // Собственная функция middleware для Express
app.get('/some/path', function(req, res) {
res.json({ custom: 'response' });
});
}
}
------------------------------------------------------------------------
performance: { // Конфигурирование как отражать информацию о производительности проведения сборки
hints: "warning", // включить или выключить подсказки по производительности
maxAssetSize: 200000, // int (in bytes), - при каких лимитах показывать подсказки по производительности
maxEntrypointSize: 400000, // int (in bytes) - при каких лимитах показывать подсказки по производительности
assetFilter: function (assetFilename) { // Какой файл использовать для оценки производительности сборки
return assetFilename.endsWith('.css') || assetFilename.endsWith('.js');
}
},
------------------------------------------------------------------------
stats: "errors-only", // Какую информацию о сборке показывать на экране консоли
stats: {
// Add asset Information
assets: true,
// Sort assets by a field
assetsSort: "field",
// Add information about cached (not built) modules
cached: true,
// Show cached assets (setting this to `false` only shows emitted files)
cachedAssets: true,
// Add children information
children: true,
// Add chunk information (setting this to `false` allows for a less verbose output)
chunks: true,
// Add built modules information to chunk information
chunkModules: true,
// Add the origins of chunks and chunk merging info
chunkOrigins: true,
// Sort the chunks by a field
chunksSort: "field",
// Context directory for request shortening
context: "../src/",
// `webpack --colors` equivalent
colors: true,
// Display the distance from the entry point for each module
depth: false,
// Display the entry points with the corresponding bundles
entrypoints: false,
// Add errors
errors: true,
// Add details to errors (like resolving log)
errorDetails: true,
// Exclude modules which match one of the given strings or regular expressions
exclude: [],
// Add the hash of the compilation
hash: true,
// Set the maximum number of modules to be shown
maxModules: 15,
// Add built modules information
modules: true,
// Sort the modules by a field
modulesSort: "field",
// Show dependencies and origin of warnings/errors (since webpack 2.5.0)
moduleTrace: true,
// Show performance hint when file size exceeds `performance.maxAssetSize`
performance: true,
// Show the exports of the modules
providedExports: false,
// Add public path information
publicPath: true,
// Add information about the reasons why modules are included
reasons: true,
// Add the source code of modules
source: true,
// Add timing information
timings: true,
// Show which exports of a module are used
usedExports: false,
// Add webpack version information
version: true,
// Add warnings
warnings: true,
// Filter warnings to be shown (since webpack 2.4.0),
// can be a String, Regexp, a function getting the warning and returning a boolean
// or an Array of a combination of the above. First match wins.
warningsFilter: "filter" | /filter/ | ["filter", /filter/] | (warning) => ... return true|false
};
------------------------------------------------------------------------
node: { // Включать ли набор разных полифилов для кода Node.js
console: false,
global: true,
process: true,
__filename: "mock",
__dirname: "mock",
Buffer: true,
setImmediate: true
dns: "mock",
fs: "empty",
path: true,
url: false
}
------------------------------------------------------------------------
amd: { // Установить значения для require.amd и define.amd для:
jQuery: true
}
------------------------------------------------------------------------
loader: '' // Передать собственные значения в контекст модуля загрузчика
-----------------------------------------------------------------------
};
------------------------------------------------------------------------
// Компиляция через команду webpack
module.exports = config;
------------------------------------------------------------------------
или
------------------------------------------------------------------------
// Компиляция через Node.js короткий способ
------------------------------------------------------------------------
// Компиляция через Node.js короткий способ
webpack(config, function (error, stats) {
console.log(error); // => fatal compiler error (rar)
var json = stats.toJson() // => webpack --json
console.log(json.errors); // => array of errors
console.log(json.warnings); // => array of warnings
console.log('Done');
}
);
------------------------------------------------------------------------
или
------------------------------------------------------------------------
// Компиляция через Node.js длинный способ
const compiler = webpack(config);
compiler.run(function(error, stats) {
console.log(stats.hasErrors());
console.log(stats.hasWarnings());
console.log(error); // => fatal compiler error (rar)
var json = stats.toJson({chunks: false, hash: true ...}) // => webpack --json
console.log(json.errors); // => array of errors
console.log(json.warnings); // => array of warnings
console.log(stats.toString({
chunks: false, // Makes the build much quieter
colors: true
}));
console.log('Done');
});
// или
const watchOptions = {
aggregateTimeout: 300, // после внесения любого изменения в файл подождать 300 секунд перед началом сборки. Вдруг еще изменения будут.
poll: true // использовать polling вместо native watchers
// можно передать число для установки polling interval
};
const watcher = compiler.watch(watchOptions, function (error, stats) {
console.log(error); // => fatal compiler error (rar)
var json = stats.toJson() // => webpack --json
console.log(json.errors); // => array of errors
console.log(json.warnings); // => array of warnings
console.log('Done');
}
);
watcher.close(function () {console.log('Watcher stoped ');}); // Остановка отслеживания изменений в файлах
------------------------------------------------------------------------
// Полный контроль и запуск Dev Server через Express
------------------------------------------------------------------------
var express = require("express");
var webpackDevMiddleware = require("webpack-dev-middleware");
var webpack = require("webpack");
var webpackConfig = require("./webpack.config");
var app = express();
var compiler = webpack(webpackConfig);
app.use(webpackDevMiddleware(compiler, {
publicPath: "/", // Same as "output.publicPath" in most cases.
filename: "bundle.js", // Same as "output.filename" in most cases.
lazy: true // lazy mode will only recompile on a request to the entry point.
}));
app.listen(3000, function () {
console.log("Listening on port 3000!");
console.log("Depending on what you've used in output.publicPath and output.filename, your bundle now available on http://localhost:3000/bundle.js");
});
понедельник, 26 июня 2017 г.
NodeJS HTTP Proxy
Файл http-proxy.js
var otherServerAnswer = Buffer.from(
JSON.stringify(
{data: [1, 2, 3]} // Ваши данные, которые вы хотите передать.
)
, 'utf-8'
);
var proxyURL = '/get/data' // null <-- Адрес, при запросе по которому, вы хотите передать ваши данные или null, если вам не нужна возврат ваших данных в ответ на запрос по указанном адресу.
, proxyServerHostname = '127.0.0.5' // Адрес промежуточного сервера.
, proxyServerPort = 80
, otherServerHostname = '127.0.0.1' // Адрес целевого сервера.
, otherServerPort = 8080;
var http = require('http')
, url = require('url');
var proxyServer = http.createServer(function (browserRequest, proxyServerResponse) {
console.log('Browser request: ' + browserRequest.method + ' ' + browserRequest.url);
var browserURL = url.parse(browserRequest.url);
var options = {
headers: browserRequest.headers
, method: browserRequest.method
, hostname: otherServerHostname
, port: otherServerPort
, path: browserURL.path
};
var proxyServerRequest = http.request(options);
browserRequest.on('data', function (chunk) {proxyServerRequest.write(chunk, 'binary');});
browserRequest.on('end', function () {proxyServerRequest.end();});
browserRequest.on('error', function (error) {console.log('Error with browser request: ' + error);});
proxyServerRequest.on('response', function (otherServerResponse) {
if (typeof browserRequest.url === 'string' && browserRequest.url === proxyURL) {
otherServerResponse.headers['content-length'] = Buffer.byteLength(otherServerAnswer);
proxyServerResponse.writeHead(otherServerResponse.statusCode, otherServerResponse.headers);
proxyServerResponse.end(otherServerAnswer, 'binary');
} else {
var chunks = [];
otherServerResponse.on('data', function (chunk) {
// Закомментированные строки для проверки правильности передачи данных.
// Конвертация из бинарных данных в строку и обратно.
// chunk = chunk.toString('utf-8');
// chunk = JSON.parse(chunk);
// chunk = JSON.stringify(chunk);
// chunk = Buffer.from(chunk, 'utf-8');
// console.log(Buffer.byteLength(chunk));
chunks.push(chunk);
});
otherServerResponse.on('end', function () {
// console.log(Buffer.concat(chunks).toString('utf-8'));
proxyServerResponse.writeHead(otherServerResponse.statusCode, otherServerResponse.headers);
proxyServerResponse.end(Buffer.concat(chunks), 'binary');
});
}
otherServerResponse.on('error', function (error) {console.log('Error with other server response: ' + error);});
});
proxyServerRequest.on('error', function (error) {console.log('Error with other proxy server request: ' + error);});
});
proxyServer.listen(proxyServerPort, proxyServerHostname, function (error) {
if (error) {throw error;}
console.log('Proxy server started at ' + proxyServerHostname + ':' + proxyServerPort);
});
////////////////////////////////////////////////////////////////////////////////
/* Пример кода целевого сервера для тестирования работы промежуточного сервера.
var otherServer = http.createServer(function (request, response) {
response.writeHead(200, {'Content-Type': 'text/html'});
response.write('OK');
response.end('BYE');
});
otherServer.listen(otherServerPort, otherServerHostname, function (error) {
if (error) {throw error;}
console.log('Other server started at ' + otherServerHostname + ':' + otherServerPort);
});
*/
var otherServerAnswer = Buffer.from(
JSON.stringify(
{data: [1, 2, 3]} // Ваши данные, которые вы хотите передать.
)
, 'utf-8'
);
var proxyURL = '/get/data' // null <-- Адрес, при запросе по которому, вы хотите передать ваши данные или null, если вам не нужна возврат ваших данных в ответ на запрос по указанном адресу.
, proxyServerHostname = '127.0.0.5' // Адрес промежуточного сервера.
, proxyServerPort = 80
, otherServerHostname = '127.0.0.1' // Адрес целевого сервера.
, otherServerPort = 8080;
var http = require('http')
, url = require('url');
var proxyServer = http.createServer(function (browserRequest, proxyServerResponse) {
console.log('Browser request: ' + browserRequest.method + ' ' + browserRequest.url);
var browserURL = url.parse(browserRequest.url);
var options = {
headers: browserRequest.headers
, method: browserRequest.method
, hostname: otherServerHostname
, port: otherServerPort
, path: browserURL.path
};
var proxyServerRequest = http.request(options);
browserRequest.on('data', function (chunk) {proxyServerRequest.write(chunk, 'binary');});
browserRequest.on('end', function () {proxyServerRequest.end();});
browserRequest.on('error', function (error) {console.log('Error with browser request: ' + error);});
proxyServerRequest.on('response', function (otherServerResponse) {
if (typeof browserRequest.url === 'string' && browserRequest.url === proxyURL) {
otherServerResponse.headers['content-length'] = Buffer.byteLength(otherServerAnswer);
proxyServerResponse.writeHead(otherServerResponse.statusCode, otherServerResponse.headers);
proxyServerResponse.end(otherServerAnswer, 'binary');
} else {
var chunks = [];
otherServerResponse.on('data', function (chunk) {
// Закомментированные строки для проверки правильности передачи данных.
// Конвертация из бинарных данных в строку и обратно.
// chunk = chunk.toString('utf-8');
// chunk = JSON.parse(chunk);
// chunk = JSON.stringify(chunk);
// chunk = Buffer.from(chunk, 'utf-8');
// console.log(Buffer.byteLength(chunk));
chunks.push(chunk);
});
otherServerResponse.on('end', function () {
// console.log(Buffer.concat(chunks).toString('utf-8'));
proxyServerResponse.writeHead(otherServerResponse.statusCode, otherServerResponse.headers);
proxyServerResponse.end(Buffer.concat(chunks), 'binary');
});
}
otherServerResponse.on('error', function (error) {console.log('Error with other server response: ' + error);});
});
proxyServerRequest.on('error', function (error) {console.log('Error with other proxy server request: ' + error);});
});
proxyServer.listen(proxyServerPort, proxyServerHostname, function (error) {
if (error) {throw error;}
console.log('Proxy server started at ' + proxyServerHostname + ':' + proxyServerPort);
});
////////////////////////////////////////////////////////////////////////////////
/* Пример кода целевого сервера для тестирования работы промежуточного сервера.
var otherServer = http.createServer(function (request, response) {
response.writeHead(200, {'Content-Type': 'text/html'});
response.write('OK');
response.end('BYE');
});
otherServer.listen(otherServerPort, otherServerHostname, function (error) {
if (error) {throw error;}
console.log('Other server started at ' + otherServerHostname + ':' + otherServerPort);
});
*/
среда, 21 июня 2017 г.
Webpack API
------------------------------------------------------------------------
Webpack API
------------------------------------------------------------------------
const path = require('path');
const webpack = require('webpack');
------------------------------------------------------------------------
const config = {
------------------------------------------------------------------------
context: path.join(__dirname, 'source'), // Абсолютный путь до папки с файлом указанным в entry. По умолчанию равно process.cwd().
------------------------------------------------------------------------
entry: './index.js', // Исходный главный файл
entry: ['./library.js', './index.js'], // Последовательный набор, идущих друг за другом исходных файлов. Последний в списке файл главный.
entry: { // Несколько разных исходных главных файлов
page1: './index1.js', // Исходный главный файл для страницы 1
page2: ['./library.js', './index2.js'] // Исходный главный файл для страницы 2
},
------------------------------------------------------------------------
output: {
path: path.join(__dirname, '/home/proj/public/dist/[hash]'), // // Абсолютный путь до папки с итоговыми файлами.
publicPath: '/dist/[hash]', // Браузерный путь до папки, где лежат итоговый файлы. Предназначен для использования вместе с Webpack Dev Server.
filename: "[name].bundle.js", // Имя итогового файла
// [name] - имя итогового файла
// [hash] - хэш итогового файла
// [chunkhash] - хэш части сборки итогового файла
chunkFilename: "[id].bundle.js", // Имя итоговой части сборки
// [id] - идентификатор части сборки
// [name] - имя части сборки
// [hash] - хэш части сборки
// [chunkhash] - хэш части сборки
sourceMapFilename: "[file].map" // Имя файлов source map, размещаемых в папке output.path
// [file] - имя итогового JavaScript-файла
// [id] - идентификатор части сборки
// [hash] хэш итогового файла
pathinfo: false, // Включать ли в итоговую сборку комментарии синформацией о модулях: require(/* ./test */23)
library: 'lib.js' // Если задано, то итоговая сборка будет экспортирована как отдельная библиотека с указанным именем. Используется только, если вы хотите собрать отдельную библиотеку.
libraryTarget: "var" // В каком формате написать экспорт содержимого библиотеки? var Library = ...library code...;
umdNamedDefine: false //Если указана output.libraryTarget и в ней установлено "umd" и указано output.library, тогда установка данного значения в true создаст имя AMD модуля
sourcePrefix: "\t" // Записать перед каждой строчкой в итоговой сборке заданную строку
crossOriginLoading: "anonymous" // Включить cross-origin loading для частей сборки
devtoolModuleFilenameTemplate: "webpack:///[resource-path]?[loaders]" // Имяфайла шаблона для генерируемых файлов source map
devtoolLineToLine: false // генерировать source map, привязанный линией к линии к исходному файлу
hotUpdateChunkFilename: "[id].[hash].hot-update.js" // имя файла для частей с горячим обновлением, размещаемых в папке output.path
// [id] - идентификатор обновления
// [hash] - хэш обновления
hotUpdateMainFilename: "[hash].hot-update.json" // имя главного ффайла с горячим обновлением, размещаемиого в папке output.path
// [hash] - хэш сборки
jsonpFunction: "webpackJsonp" // Имя функци JSONP, используемой Webpack для асинхронной загрузки частей сборки
hotUpdateFunction: "webpackHotUpdate" // Имя функци JSONP, используемой Webpack для асинхронной загрузки обновлений частей сборки
},
------------------------------------------------------------------------
externals: { // Перечень модулей, которые не должны быть включены в итоговую сборку, а должны быть вынесены в отдельные файлы
{
a: false, // модуль a не будет вынесен во вне
b: true, // модуль b будет вынесен во вне `module.exports = b`
"./c": "c", // модуль "./c" будет вынесен во вне `module.exports = c`
"./d": "var d", // модуль "./d" будет вынесен во вне `module.exports = ./d` <-- здесь будет синтакическая ошибка
"./f": "commonjs ./a/b", // модуль "./f" будет вынесен во вне `module.exports = require("./a/b")`
"./f": "this ./a/b" // модуль "./f" будет вынесен во вне `(function() { module.exports = this["./a/b"]; }())`
},
/^[a-z\-0-9]+$/, // Каждый модуль не входящий в это выражение будет вынесен во вне abc -> require("abc")
function(context, request, callback) { // Какждый модуль, имеющий в своем имени префикс "global-" будет вынесен во вне "global-abc" -> abc
if(/^global-/.test(request)) {return callback(null, "var " + request.substr(7));}
callback();
},
"./e" // модуль "./e" будет вынесен во вне (require("./e"))
},
------------------------------------------------------------------------
module: { // Как загружать модули JavaScript в сборку
resolveLoader: { // Где искать загрузчики модулей
// Имеет такой же набор опций, что и resolve для файлов, но только для загрузчиков модулей, кроме moduleTemplates, которого у resolve нет
moduleTemplates: ["*-webpack-loader", "*-web-loader", "*-loader", "*"] // Массив с перечнем альтернативных имен для загрузчиков модулей
extensions: ["", ".webpack-loader.js", ".web-loader.js", ".loader.js", ".js"], // Массив расширений загрузчиков модулей
packageMains: ["webpackLoader", "webLoader", "loader", "main"] // Просматривать перечисленные свойства в файлах package.json для поиска загрузчиков модулей
root: path.join(__dirname, "node_modules") // Путь до папки в которой надо искать загрузчики модулей
modulesDirectories: ["web_loaders", "web_modules", "node_loaders", "node_modules"], // Массив имен папок внутри данной директории, в которых надо искать загрузчики модулей.
// Это подобие тому, как Node.js ищет папки с имене "node_modules". Обычно достаточно указать только область поиска в resolveLoader.root.
fallback: [ // Массив с перечнем директорий в которых нужно искать загрузчики модулей, если Webpack не обнаружит нужные загрузчики модулей в папках указананнх в resolveLoader.root и resolveLoader.modulesDirectories.
path.resolve('./some/modules'), // Все пути обязательно должны быть абсолютными!
path.resolve('./other/modules')
]
alias: { // Заменить имя загрузчика модуля на его полное имя
txt: 'raw-loader'
}
packageAlias: "browser" // Найти в файле package.json свойства с указанным именем и использовать его содержимое вместо resolveLoader.alias
unsafeCache: [/some.js/] // Включить небезопасное кэширование
}
resolve: { // Где искать исходные файлы для сборки
extensions: ["", ".webpack.js", ".web.js", ".js", ".json", ".coffee"] // Массив расширений исходных файлов которые надо включать в сборку
packageMains: ["webpack", "browser", "web", "browserify", ["jam", "main"], "main"] // Просматривать перечисленные свойства в файлах package.json для поиска исходных файлов для сборки
root: [ // Массив с перечнем директорий в которых нужно искать исходные файлы.
path.resolve('./app/modules'), // Все пути обязательно должны быть абсолютными!
path.resolve('./vendor/modules')
]
modulesDirectories: [ // Массив имен папок внутри данной директории, в которых надо искать исходные файлы.
// Это подобие тому, как Node.js ищет папки с имене "node_modules". Обычно достаточно указать только область поиска в resolve.root.
"web_modules",
"node_modules"
]
fallback: [ // Массив с перечнем директорий в которых нужно искать исходные файлы, если Webpack не обнаружит нужные исходные файлы в папках указананнх в resolve.root и resolve.modulesDirectories.
path.resolve('./some/modules'), // Все пути обязательно должны быть абсолютными!
path.resolve('./other/modules')
]
alias: { // Заменить имя модуля в импорте на путь до файла
main: "/absolute/path/to/file/main.js"
sum: "/absolute/path/to/file/sum.js"
}
packageAlias: "browser" // Найти в файле package.json свойства с указанным именем и использовать его содержимое вместо resolve.alias
unsafeCache: [/some.js/] // Включить небезопасное кэширование
}
noParse: [/\.ts$/, /\.tsx$/] // Не парсить перед сборкой файлы, перечисленные в данном массиве. Ожидается, что эти файлы сами ничего не импортирую. В них есть только экспорт exports и module.exports.
preLoaders: [ // Массив с перечнем используемых загрузчиков модулей JavaScript для предварительной обработки перед сборкой
test: test: /\.js$/, // Регулярное выражение для поиска файлов, загружаемых данным загрузчиком модулей
exclude: /node_modules/, // Регулярное выражение для поиска которые нельзя, загружаемых данным загрузчиком модулей
include: ['/source/file2.js', '/source/file3.js'] // Массив путей до файлов, которые тоже нужно загружать данным загрузчиком модулей
// Внимание! Webpack ищет загрузчики модулей относительно файла с конфигом. Если ваши загрузчики установлены в папке node_modules вне в родительской директории,
// то Webpack не сможет их сам найти.
// В этом случае необходимо добавить папку node_modules с модулями загрузчиками как абсолютный путь в опцию resolveLoader.root
loader: 'style-loader?mimetype=image/png!css-loader?mimetype=image/png' // Строка с перечнем модулей загрузчиков, используемых для загрузки данных типов файлов, разделенных знаком "!", и выполняющихся справа налево
query: { // Объект с перечнем настроек для loader, если он указан только один. В противном случае перечень настроек указывается внутри строки загрузчика.
mimetype: 'image/png'
}
// Используется или loader или loaders
loaders: [ // Массив с перечнем модулей загрузчиков, используемых для загрузки данных типов файлов, и выполняющихся с конца в начало
'style-loader?mimetype=image/png',
'css-loader?mimetype=image/png'
]
],
loaders: [ // Массив с перечнем используемых загрузчиков модулей JavaScript в сборку
test: test: /\.js$/, // Регулярное выражение для поиска файлов, загружаемых данным загрузчиком модулей
exclude: /node_modules/, // Регулярное выражение для поиска которые нельзя, загружаемых данным загрузчиком модулей
include: ['/source/file2.js', '/source/file3.js'] // Массив путей до файлов, которые тоже нужно загружать данным загрузчиком модулей
// Внимание! Webpack ищет загрузчики модулей относительно файла с конфигом. Если ваши загрузчики установлены в папке node_modules вне в родительской директории,
// то Webpack не сможет их сам найти.
// В этом случае необходимо добавить папку node_modules с модулями загрузчиками как абсолютный путь в опцию resolveLoader.root
loader: 'style-loader?mimetype=image/png!css-loader?mimetype=image/png' // Строка с перечнем модулей загрузчиков, используемых для загрузки данных типов файлов, разделенных знаком "!", и выполняющихся справа налево
query: { // Объект с перечнем настроек для loader, если он указан только один. В противном случае перечень настроек указывается внутри строки загрузчика.
mimetype: 'image/png'
}
// Используется или loader или loaders
loaders: [ // Массив с перечнем модулей загрузчиков, используемых для загрузки данных типов файлов, и выполняющихся с конца в начало
'style-loader?mimetype=image/png',
'css-loader?mimetype=image/png'
]
]
postLoaders: [ // Массив с перечнем используемых загрузчиков модулей JavaScript для обработки после сборки
test: test: /\.js$/, // Регулярное выражение для поиска файлов, загружаемых данным загрузчиком модулей
exclude: /node_modules/, // Регулярное выражение для поиска которые нельзя, загружаемых данным загрузчиком модулей
include: ['/source/file2.js', '/source/file3.js'] // Массив путей до файлов, которые тоже нужно загружать данным загрузчиком модулей
// Внимание! Webpack ищет загрузчики модулей относительно файла с конфигом. Если ваши загрузчики установлены в папке node_modules вне в родительской директории,
// то Webpack не сможет их сам найти.
// В этом случае необходимо добавить папку node_modules с модулями загрузчиками как абсолютный путь в опцию resolveLoader.root
loader: 'style-loader?mimetype=image/png!css-loader?mimetype=image/png' // Строка с перечнем модулей загрузчиков, используемых для загрузки данных типов файлов, разделенных знаком "!", и выполняющихся справа налево
query: { // Объект с перечнем настроек для loader, если он указан только один. В противном случае перечень настроек указывается внутри строки загрузчика.
mimetype: 'image/png'
}
// Используется или loader или loaders
loaders: [ // Массив с перечнем модулей загрузчиков, используемых для загрузки данных типов файлов, и выполняющихся с конца в начало
'style-loader?mimetype=image/png',
'css-loader?mimetype=image/png'
]
]
// Отключить обработку неизвестных require
unknownContextRegExp: /$^/,
unknownContextCritical: false,
// Отключить обработку require с единственным выражением
exprContextRegExp: /$^/,
exprContextCritical: false,
// Предупредить о каждом обнаруженном выражении в require
wrappedContextCritical: true
},
------------------------------------------------------------------------
plugins: [ // Массив с перечнем плагинов, вызываемых по очередние к содержимому итоговой сборки
new webpack.IgnorePlugin(/file\.js$/),
new webpack.optimize.UglifyJsPlugin({
compress: {
warnings: false
},
output: {
comments: false
}
}),
new ComponentPlugin()
]
------------------------------------------------------------------------
target: 'web' // Скомпмилировать сборку для использования в браузере
------------------------------------------------------------------------
bail: true // Прервать сборку при обнаружении хоть одной ошибки
------------------------------------------------------------------------
profile: true // Получать информацию о времени сборки каждого модуля
------------------------------------------------------------------------
cache: true // Кэшировать сборку для ускорения пересборки
------------------------------------------------------------------------
debug: true // Переключить работу загрузчиков модулей в режим отладки
------------------------------------------------------------------------
watch: true // Отслеживать изменения файлов и запускать пересборку
------------------------------------------------------------------------
devtool: 'eval' // В какмо виде произовдить сборку source map
------------------------------------------------------------------------
devServer: { // конфиг для webpack-dev-server
contentBase: "./build",
}
------------------------------------------------------------------------
node: { // Включать ли набор разных полифилов для кода Node.js
console: false,
global: true,
process: true,
Buffer: true,
__filename: "mock",
__dirname: "mock",
setImmediate: true
}
------------------------------------------------------------------------
amd: { // Установить значения для require.amd и define.amd для:
jQuery: true
}
------------------------------------------------------------------------
};
------------------------------------------------------------------------
// Компиляция через команду webpack
module.exports = config;
------------------------------------------------------------------------
или
------------------------------------------------------------------------
// Компиляция через Node.js короткий способ
webpack(config, function (error, stats) {
console.log(error); // => fatal compiler error (rar)
var json = stats.toJson() // => webpack --json
console.log(json.errors); // => array of errors
console.log(json.warnings); // => array of warnings
console.log('Done');
}
);
------------------------------------------------------------------------
или
------------------------------------------------------------------------
// Компиляция через Node.js длинный способ
const compiler = webpack(config);
compiler.run(function(error, stats) {
console.log(stats.hasErrors());
console.log(stats.hasWarnings());
console.log(error); // => fatal compiler error (rar)
var json = stats.toJson({chunks: false, hash: true ...}) // => webpack --json
console.log(json.errors); // => array of errors
console.log(json.warnings); // => array of warnings
console.log(stats.toString({
chunks: false, // Makes the build much quieter
colors: true
}));
console.log('Done');
});
// или
const watchOptions = {
aggregateTimeout: 300, // после внесения любого изменения в файл подождать 300 секунд перед началом сборки. Вдруг еще изменения будут.
poll: true // использовать polling вместо native watchers
// можно передать число для установки polling interval
};
const watcher = compiler.watch(watchOptions, function (error, stats) {
console.log(error); // => fatal compiler error (rar)
var json = stats.toJson() // => webpack --json
console.log(json.errors); // => array of errors
console.log(json.warnings); // => array of warnings
console.log('Done');
}
);
watcher.close(function () {console.log('Watcher stoped ');}); // Остановка отслеживания изменений в файлах
------------------------------------------------------------------------
// Dev Server
var WebpackDevServer = require("webpack-dev-server");
var webpack = require("webpack");
var fs = require("fs");
var compiler = webpack({
// configuration
});
var server = new WebpackDevServer(compiler, {
// webpack-dev-server options
contentBase: "/path/to/directory",
// Can also be an array, or: contentBase: "http://localhost/",
hot: true,
// Enable special support for Hot Module Replacement
// Page is no longer updated, but a "webpackHotUpdate" message is sent to the content
// Use "webpack/hot/dev-server" as additional module in your entry point
// Note: this does _not_ add the `HotModuleReplacementPlugin` like the CLI option does.
historyApiFallback: {
rewrites: [
// shows views/landing.html as the landing page
{ from: /^\/$/, to: '/views/landing.html' },
// shows views/subpage.html for all routes starting with /subpage
{ from: /^\/subpage/, to: '/views/subpage.html' },
// shows views/404.html on all other pages
{ from: /./, to: '/views/404.html' },
],
},
// Set this as true if you want to access dev server from arbitrary url.
// This is handy if you are using a html5 router.
compress: true,
// Set this if you want to enable gzip compression for assets
proxy: {
"**": "http://localhost:9090"
},
// Set this if you want webpack-dev-server to delegate a single path to an arbitrary server.
// Use "**" to proxy all paths to the specified server.
// This is useful if you want to get rid of 'http://localhost:8080/' in script[src],
// and has many other use cases (see https://github.com/webpack/webpack-dev-server/pull/127 ).
setup: function(app) {
// Here you can access the Express app object and add your own custom middleware to it.
// For example, to define custom handlers for some paths:
// app.get('/some/path', function(req, res) {
// res.json({ custom: 'response' });
// });
},
// pass [static options](http://expressjs.com/en/4x/api.html#express.static) to inner express server
staticOptions: {
},
clientLogLevel: "info",
// Control the console log messages shown in the browser when using inline mode. Can be `error`, `warning`, `info` or `none`.
// webpack-dev-middleware options
quiet: false,
noInfo: false,
lazy: true,
filename: "bundle.js",
watchOptions: {
aggregateTimeout: 300,
poll: 1000
},
// It's a required option.
publicPath: "/assets/",
headers: { "X-Custom-Header": "yes" },
stats: { colors: true },
https: {
cert: fs.readFileSync("path-to-cert-file.pem"),
key: fs.readFileSync("path-to-key-file.pem"),
cacert: fs.readFileSync("path-to-cacert-file.pem")
}
});
server.listen(8080, "localhost", function() {});
// server.close();
------------------------------------------------------------------------
// Dev Server Middleware
const webpackDevMiddleware = require("webpack-dev-middleware");
const webpack = require("webpack");
const compiler = webpack(config);
app.use(webpackDevMiddleware(compiler, {
publicPath: config.output.publicPath
filename: config.output.filename
watchOptions: {
aggregateTimeout: 300
poll: true
}
noInfo: true
quiet: false
lazy: false
stats: true
headers: {
"X-Custom-Header": "yes"
}
}));
------------------------------------------------------------------------
==================================================================
==================================================================
const webpack = require('webpack');
const ComponentPlugin = require('component-webpack-plugin');
module.exports = {
==================================================================
entry: './src/app.js',
entry: {
beep: './beep.js',
boop: './boop.js',
},
entry: {
app: './app.js',
vendor: ['jquery', 'underscore', ...]
},
output: {
filename: 'bundle.js'
},
plugins: [
new webpack.optimize.CommonsChunkPlugin(/* entry= */'vendor', /* filename= */'vendor.bundle.js')
]
<script src='vendor.bundle.js'></script>
<script src='bundle.js'></script>
module.exports = {
entry: {
a: './a',
b: './b'
},
output: {
filename: '[name].js'
},
plugins: [
new webpack.optimize.CommonsChunkPlugin('init.js')
]
}
<script src='init.js'></script>
<script src='a.js'></script>
<script src='b.js'></script>
==================================================================
output: { // './bin/app.bundle.js'
path: './bin',
filename: 'app.bundle.js' // '[name].bundle.js'
=============================
path: path.join(__dirname, 'assets', '[hash]'),
publicPath: 'assets/[hash]/',
filename: 'output.[hash].bundle.js',
chunkFilename: '[id].[hash].bundle.js'
},
output: {
libraryTarget: 'var', // export itself to a global var
library: 'Foo' // name of the global var: 'Foo'
},
externals: {
jquery: 'jQuery' // require('jquery') is external and available on the global var jQuery
}
==================================================================
resolve: {
extensions: ['', '.js', '.coffee'],
fallback: path.join(__dirname, 'node_modules')
},
resolveLoader: {
fallback: path.join(__dirname, 'node_modules')
},
module: {
loaders: [
{
test: /\.js$/,
exclude: /node_modules/,
loader: 'babel-loader?mimetype=image/png'
},
{
test: /\.css$/,
loaders: [
'style-loader?mimetype=image/png',
'css-loader?mimetype=image/png'
]
},
{
test: /\.png$/,
loader: 'url-loader',
query: {
mimetype: 'image/png'
}
},
{
test: /\.jsx?$/,
exclude: /(node_modules|bower_components)/,
loaders: [{
loader: 'babel-loader',
query: {
cacheDirectory: true
}
}
]
},
plugins: [
new webpack.IgnorePlugin(/file\.js$/),
new webpack.optimize.UglifyJsPlugin({
compress: {
warnings: false
},
output: {
comments: false
}
}),
new ComponentPlugin()
]
};
==================================================================
var webpack = require('webpack');
webpack(
{
entry: './main.js',
output: {
filename: 'bundle.js'
}
}
, function(err, stats) {
console.log(err); // => fatal compiler error (rar)
var json = stats.toJson() // => webpack --json
console.log(json.errors); // => array of errors
console.log(json.warnings); // => array of warnings
}
);
==================================================================
var ExtractTextPlugin = require('extract-text-webpack-plugin');
module.exports = {
entry: {
posts: './posts',
post: './post',
about: './about'
},
output: {
filename: '[name].js',
chunkFilename: '[id].js'
},
module: {
loaders: [
{
test: /\.css$/,
loader: ExtractTextPlugin.extract('style-loader', 'css-loader')
},
{
test: /\.less$/,
loader: ExtractTextPlugin.extract('style-loader', 'css-loader!less-loader')
}
]
},
plugins: [
new ExtractTextPlugin('[name].css')
]
}
Output files:
posts.js
posts.css
post.js
post.css
about.js
about.css
Styles in Commons Chunk
// ...
module.exports = {
// ...
plugins: [
new webpack.optimize.CommonsChunkPlugin('commons', 'commons.js'),
new ExtractTextPlugin('[name].css')
]
}
Output files:
commons.js
commons.css
posts.js
posts.css
post.js
post.css
about.js
about.css
==================================================================
var CommonsChunkPlugin = require('webpack/lib/optimize/CommonsChunkPlugin');
module.exports = {
entry: {
p1: './page1',
p2: './page2',
p3: './page3',
ap1: './admin/page1',
ap2: './admin/page2'
},
output: {
filename: '[name].js'
},
plugins: [
new CommonsChunkPlugin('admin-commons.js', ['ap1', 'ap2']),
new CommonsChunkPlugin('commons.js', ['p1', 'p2', 'admin-commons.js'])
]
};
// <script>s required:
// page1.html: commons.js, p1.js
// page2.html: commons.js, p2.js
// page3.html: p3.js
// admin-page1.html: commons.js, admin-commons.js, ap1.js
// admin-page2.html: commons.js, admin-commons.js, ap2.js
Webpack API
------------------------------------------------------------------------
const path = require('path');
const webpack = require('webpack');
------------------------------------------------------------------------
const config = {
------------------------------------------------------------------------
context: path.join(__dirname, 'source'), // Абсолютный путь до папки с файлом указанным в entry. По умолчанию равно process.cwd().
------------------------------------------------------------------------
entry: './index.js', // Исходный главный файл
entry: ['./library.js', './index.js'], // Последовательный набор, идущих друг за другом исходных файлов. Последний в списке файл главный.
entry: { // Несколько разных исходных главных файлов
page1: './index1.js', // Исходный главный файл для страницы 1
page2: ['./library.js', './index2.js'] // Исходный главный файл для страницы 2
},
------------------------------------------------------------------------
output: {
path: path.join(__dirname, '/home/proj/public/dist/[hash]'), // // Абсолютный путь до папки с итоговыми файлами.
publicPath: '/dist/[hash]', // Браузерный путь до папки, где лежат итоговый файлы. Предназначен для использования вместе с Webpack Dev Server.
filename: "[name].bundle.js", // Имя итогового файла
// [name] - имя итогового файла
// [hash] - хэш итогового файла
// [chunkhash] - хэш части сборки итогового файла
chunkFilename: "[id].bundle.js", // Имя итоговой части сборки
// [id] - идентификатор части сборки
// [name] - имя части сборки
// [hash] - хэш части сборки
// [chunkhash] - хэш части сборки
sourceMapFilename: "[file].map" // Имя файлов source map, размещаемых в папке output.path
// [file] - имя итогового JavaScript-файла
// [id] - идентификатор части сборки
// [hash] хэш итогового файла
pathinfo: false, // Включать ли в итоговую сборку комментарии синформацией о модулях: require(/* ./test */23)
library: 'lib.js' // Если задано, то итоговая сборка будет экспортирована как отдельная библиотека с указанным именем. Используется только, если вы хотите собрать отдельную библиотеку.
libraryTarget: "var" // В каком формате написать экспорт содержимого библиотеки? var Library = ...library code...;
umdNamedDefine: false //Если указана output.libraryTarget и в ней установлено "umd" и указано output.library, тогда установка данного значения в true создаст имя AMD модуля
sourcePrefix: "\t" // Записать перед каждой строчкой в итоговой сборке заданную строку
crossOriginLoading: "anonymous" // Включить cross-origin loading для частей сборки
devtoolModuleFilenameTemplate: "webpack:///[resource-path]?[loaders]" // Имяфайла шаблона для генерируемых файлов source map
devtoolLineToLine: false // генерировать source map, привязанный линией к линии к исходному файлу
hotUpdateChunkFilename: "[id].[hash].hot-update.js" // имя файла для частей с горячим обновлением, размещаемых в папке output.path
// [id] - идентификатор обновления
// [hash] - хэш обновления
hotUpdateMainFilename: "[hash].hot-update.json" // имя главного ффайла с горячим обновлением, размещаемиого в папке output.path
// [hash] - хэш сборки
jsonpFunction: "webpackJsonp" // Имя функци JSONP, используемой Webpack для асинхронной загрузки частей сборки
hotUpdateFunction: "webpackHotUpdate" // Имя функци JSONP, используемой Webpack для асинхронной загрузки обновлений частей сборки
},
------------------------------------------------------------------------
externals: { // Перечень модулей, которые не должны быть включены в итоговую сборку, а должны быть вынесены в отдельные файлы
{
a: false, // модуль a не будет вынесен во вне
b: true, // модуль b будет вынесен во вне `module.exports = b`
"./c": "c", // модуль "./c" будет вынесен во вне `module.exports = c`
"./d": "var d", // модуль "./d" будет вынесен во вне `module.exports = ./d` <-- здесь будет синтакическая ошибка
"./f": "commonjs ./a/b", // модуль "./f" будет вынесен во вне `module.exports = require("./a/b")`
"./f": "this ./a/b" // модуль "./f" будет вынесен во вне `(function() { module.exports = this["./a/b"]; }())`
},
/^[a-z\-0-9]+$/, // Каждый модуль не входящий в это выражение будет вынесен во вне abc -> require("abc")
function(context, request, callback) { // Какждый модуль, имеющий в своем имени префикс "global-" будет вынесен во вне "global-abc" -> abc
if(/^global-/.test(request)) {return callback(null, "var " + request.substr(7));}
callback();
},
"./e" // модуль "./e" будет вынесен во вне (require("./e"))
},
------------------------------------------------------------------------
module: { // Как загружать модули JavaScript в сборку
resolveLoader: { // Где искать загрузчики модулей
// Имеет такой же набор опций, что и resolve для файлов, но только для загрузчиков модулей, кроме moduleTemplates, которого у resolve нет
moduleTemplates: ["*-webpack-loader", "*-web-loader", "*-loader", "*"] // Массив с перечнем альтернативных имен для загрузчиков модулей
extensions: ["", ".webpack-loader.js", ".web-loader.js", ".loader.js", ".js"], // Массив расширений загрузчиков модулей
packageMains: ["webpackLoader", "webLoader", "loader", "main"] // Просматривать перечисленные свойства в файлах package.json для поиска загрузчиков модулей
root: path.join(__dirname, "node_modules") // Путь до папки в которой надо искать загрузчики модулей
modulesDirectories: ["web_loaders", "web_modules", "node_loaders", "node_modules"], // Массив имен папок внутри данной директории, в которых надо искать загрузчики модулей.
// Это подобие тому, как Node.js ищет папки с имене "node_modules". Обычно достаточно указать только область поиска в resolveLoader.root.
fallback: [ // Массив с перечнем директорий в которых нужно искать загрузчики модулей, если Webpack не обнаружит нужные загрузчики модулей в папках указананнх в resolveLoader.root и resolveLoader.modulesDirectories.
path.resolve('./some/modules'), // Все пути обязательно должны быть абсолютными!
path.resolve('./other/modules')
]
alias: { // Заменить имя загрузчика модуля на его полное имя
txt: 'raw-loader'
}
packageAlias: "browser" // Найти в файле package.json свойства с указанным именем и использовать его содержимое вместо resolveLoader.alias
unsafeCache: [/some.js/] // Включить небезопасное кэширование
}
resolve: { // Где искать исходные файлы для сборки
extensions: ["", ".webpack.js", ".web.js", ".js", ".json", ".coffee"] // Массив расширений исходных файлов которые надо включать в сборку
packageMains: ["webpack", "browser", "web", "browserify", ["jam", "main"], "main"] // Просматривать перечисленные свойства в файлах package.json для поиска исходных файлов для сборки
root: [ // Массив с перечнем директорий в которых нужно искать исходные файлы.
path.resolve('./app/modules'), // Все пути обязательно должны быть абсолютными!
path.resolve('./vendor/modules')
]
modulesDirectories: [ // Массив имен папок внутри данной директории, в которых надо искать исходные файлы.
// Это подобие тому, как Node.js ищет папки с имене "node_modules". Обычно достаточно указать только область поиска в resolve.root.
"web_modules",
"node_modules"
]
fallback: [ // Массив с перечнем директорий в которых нужно искать исходные файлы, если Webpack не обнаружит нужные исходные файлы в папках указананнх в resolve.root и resolve.modulesDirectories.
path.resolve('./some/modules'), // Все пути обязательно должны быть абсолютными!
path.resolve('./other/modules')
]
alias: { // Заменить имя модуля в импорте на путь до файла
main: "/absolute/path/to/file/main.js"
sum: "/absolute/path/to/file/sum.js"
}
packageAlias: "browser" // Найти в файле package.json свойства с указанным именем и использовать его содержимое вместо resolve.alias
unsafeCache: [/some.js/] // Включить небезопасное кэширование
}
noParse: [/\.ts$/, /\.tsx$/] // Не парсить перед сборкой файлы, перечисленные в данном массиве. Ожидается, что эти файлы сами ничего не импортирую. В них есть только экспорт exports и module.exports.
preLoaders: [ // Массив с перечнем используемых загрузчиков модулей JavaScript для предварительной обработки перед сборкой
test: test: /\.js$/, // Регулярное выражение для поиска файлов, загружаемых данным загрузчиком модулей
exclude: /node_modules/, // Регулярное выражение для поиска которые нельзя, загружаемых данным загрузчиком модулей
include: ['/source/file2.js', '/source/file3.js'] // Массив путей до файлов, которые тоже нужно загружать данным загрузчиком модулей
// Внимание! Webpack ищет загрузчики модулей относительно файла с конфигом. Если ваши загрузчики установлены в папке node_modules вне в родительской директории,
// то Webpack не сможет их сам найти.
// В этом случае необходимо добавить папку node_modules с модулями загрузчиками как абсолютный путь в опцию resolveLoader.root
loader: 'style-loader?mimetype=image/png!css-loader?mimetype=image/png' // Строка с перечнем модулей загрузчиков, используемых для загрузки данных типов файлов, разделенных знаком "!", и выполняющихся справа налево
query: { // Объект с перечнем настроек для loader, если он указан только один. В противном случае перечень настроек указывается внутри строки загрузчика.
mimetype: 'image/png'
}
// Используется или loader или loaders
loaders: [ // Массив с перечнем модулей загрузчиков, используемых для загрузки данных типов файлов, и выполняющихся с конца в начало
'style-loader?mimetype=image/png',
'css-loader?mimetype=image/png'
]
],
loaders: [ // Массив с перечнем используемых загрузчиков модулей JavaScript в сборку
test: test: /\.js$/, // Регулярное выражение для поиска файлов, загружаемых данным загрузчиком модулей
exclude: /node_modules/, // Регулярное выражение для поиска которые нельзя, загружаемых данным загрузчиком модулей
include: ['/source/file2.js', '/source/file3.js'] // Массив путей до файлов, которые тоже нужно загружать данным загрузчиком модулей
// Внимание! Webpack ищет загрузчики модулей относительно файла с конфигом. Если ваши загрузчики установлены в папке node_modules вне в родительской директории,
// то Webpack не сможет их сам найти.
// В этом случае необходимо добавить папку node_modules с модулями загрузчиками как абсолютный путь в опцию resolveLoader.root
loader: 'style-loader?mimetype=image/png!css-loader?mimetype=image/png' // Строка с перечнем модулей загрузчиков, используемых для загрузки данных типов файлов, разделенных знаком "!", и выполняющихся справа налево
query: { // Объект с перечнем настроек для loader, если он указан только один. В противном случае перечень настроек указывается внутри строки загрузчика.
mimetype: 'image/png'
}
// Используется или loader или loaders
loaders: [ // Массив с перечнем модулей загрузчиков, используемых для загрузки данных типов файлов, и выполняющихся с конца в начало
'style-loader?mimetype=image/png',
'css-loader?mimetype=image/png'
]
]
postLoaders: [ // Массив с перечнем используемых загрузчиков модулей JavaScript для обработки после сборки
test: test: /\.js$/, // Регулярное выражение для поиска файлов, загружаемых данным загрузчиком модулей
exclude: /node_modules/, // Регулярное выражение для поиска которые нельзя, загружаемых данным загрузчиком модулей
include: ['/source/file2.js', '/source/file3.js'] // Массив путей до файлов, которые тоже нужно загружать данным загрузчиком модулей
// Внимание! Webpack ищет загрузчики модулей относительно файла с конфигом. Если ваши загрузчики установлены в папке node_modules вне в родительской директории,
// то Webpack не сможет их сам найти.
// В этом случае необходимо добавить папку node_modules с модулями загрузчиками как абсолютный путь в опцию resolveLoader.root
loader: 'style-loader?mimetype=image/png!css-loader?mimetype=image/png' // Строка с перечнем модулей загрузчиков, используемых для загрузки данных типов файлов, разделенных знаком "!", и выполняющихся справа налево
query: { // Объект с перечнем настроек для loader, если он указан только один. В противном случае перечень настроек указывается внутри строки загрузчика.
mimetype: 'image/png'
}
// Используется или loader или loaders
loaders: [ // Массив с перечнем модулей загрузчиков, используемых для загрузки данных типов файлов, и выполняющихся с конца в начало
'style-loader?mimetype=image/png',
'css-loader?mimetype=image/png'
]
]
// Отключить обработку неизвестных require
unknownContextRegExp: /$^/,
unknownContextCritical: false,
// Отключить обработку require с единственным выражением
exprContextRegExp: /$^/,
exprContextCritical: false,
// Предупредить о каждом обнаруженном выражении в require
wrappedContextCritical: true
},
------------------------------------------------------------------------
plugins: [ // Массив с перечнем плагинов, вызываемых по очередние к содержимому итоговой сборки
new webpack.IgnorePlugin(/file\.js$/),
new webpack.optimize.UglifyJsPlugin({
compress: {
warnings: false
},
output: {
comments: false
}
}),
new ComponentPlugin()
]
------------------------------------------------------------------------
target: 'web' // Скомпмилировать сборку для использования в браузере
------------------------------------------------------------------------
bail: true // Прервать сборку при обнаружении хоть одной ошибки
------------------------------------------------------------------------
profile: true // Получать информацию о времени сборки каждого модуля
------------------------------------------------------------------------
cache: true // Кэшировать сборку для ускорения пересборки
------------------------------------------------------------------------
debug: true // Переключить работу загрузчиков модулей в режим отладки
------------------------------------------------------------------------
watch: true // Отслеживать изменения файлов и запускать пересборку
------------------------------------------------------------------------
devtool: 'eval' // В какмо виде произовдить сборку source map
------------------------------------------------------------------------
devServer: { // конфиг для webpack-dev-server
contentBase: "./build",
}
------------------------------------------------------------------------
node: { // Включать ли набор разных полифилов для кода Node.js
console: false,
global: true,
process: true,
Buffer: true,
__filename: "mock",
__dirname: "mock",
setImmediate: true
}
------------------------------------------------------------------------
amd: { // Установить значения для require.amd и define.amd для:
jQuery: true
}
------------------------------------------------------------------------
};
------------------------------------------------------------------------
// Компиляция через команду webpack
module.exports = config;
------------------------------------------------------------------------
или
------------------------------------------------------------------------
// Компиляция через Node.js короткий способ
webpack(config, function (error, stats) {
console.log(error); // => fatal compiler error (rar)
var json = stats.toJson() // => webpack --json
console.log(json.errors); // => array of errors
console.log(json.warnings); // => array of warnings
console.log('Done');
}
);
------------------------------------------------------------------------
или
------------------------------------------------------------------------
// Компиляция через Node.js длинный способ
const compiler = webpack(config);
compiler.run(function(error, stats) {
console.log(stats.hasErrors());
console.log(stats.hasWarnings());
console.log(error); // => fatal compiler error (rar)
var json = stats.toJson({chunks: false, hash: true ...}) // => webpack --json
console.log(json.errors); // => array of errors
console.log(json.warnings); // => array of warnings
console.log(stats.toString({
chunks: false, // Makes the build much quieter
colors: true
}));
console.log('Done');
});
// или
const watchOptions = {
aggregateTimeout: 300, // после внесения любого изменения в файл подождать 300 секунд перед началом сборки. Вдруг еще изменения будут.
poll: true // использовать polling вместо native watchers
// можно передать число для установки polling interval
};
const watcher = compiler.watch(watchOptions, function (error, stats) {
console.log(error); // => fatal compiler error (rar)
var json = stats.toJson() // => webpack --json
console.log(json.errors); // => array of errors
console.log(json.warnings); // => array of warnings
console.log('Done');
}
);
watcher.close(function () {console.log('Watcher stoped ');}); // Остановка отслеживания изменений в файлах
------------------------------------------------------------------------
// Dev Server
var WebpackDevServer = require("webpack-dev-server");
var webpack = require("webpack");
var fs = require("fs");
var compiler = webpack({
// configuration
});
var server = new WebpackDevServer(compiler, {
// webpack-dev-server options
contentBase: "/path/to/directory",
// Can also be an array, or: contentBase: "http://localhost/",
hot: true,
// Enable special support for Hot Module Replacement
// Page is no longer updated, but a "webpackHotUpdate" message is sent to the content
// Use "webpack/hot/dev-server" as additional module in your entry point
// Note: this does _not_ add the `HotModuleReplacementPlugin` like the CLI option does.
historyApiFallback: {
rewrites: [
// shows views/landing.html as the landing page
{ from: /^\/$/, to: '/views/landing.html' },
// shows views/subpage.html for all routes starting with /subpage
{ from: /^\/subpage/, to: '/views/subpage.html' },
// shows views/404.html on all other pages
{ from: /./, to: '/views/404.html' },
],
},
// Set this as true if you want to access dev server from arbitrary url.
// This is handy if you are using a html5 router.
compress: true,
// Set this if you want to enable gzip compression for assets
proxy: {
"**": "http://localhost:9090"
},
// Set this if you want webpack-dev-server to delegate a single path to an arbitrary server.
// Use "**" to proxy all paths to the specified server.
// This is useful if you want to get rid of 'http://localhost:8080/' in script[src],
// and has many other use cases (see https://github.com/webpack/webpack-dev-server/pull/127 ).
setup: function(app) {
// Here you can access the Express app object and add your own custom middleware to it.
// For example, to define custom handlers for some paths:
// app.get('/some/path', function(req, res) {
// res.json({ custom: 'response' });
// });
},
// pass [static options](http://expressjs.com/en/4x/api.html#express.static) to inner express server
staticOptions: {
},
clientLogLevel: "info",
// Control the console log messages shown in the browser when using inline mode. Can be `error`, `warning`, `info` or `none`.
// webpack-dev-middleware options
quiet: false,
noInfo: false,
lazy: true,
filename: "bundle.js",
watchOptions: {
aggregateTimeout: 300,
poll: 1000
},
// It's a required option.
publicPath: "/assets/",
headers: { "X-Custom-Header": "yes" },
stats: { colors: true },
https: {
cert: fs.readFileSync("path-to-cert-file.pem"),
key: fs.readFileSync("path-to-key-file.pem"),
cacert: fs.readFileSync("path-to-cacert-file.pem")
}
});
server.listen(8080, "localhost", function() {});
// server.close();
------------------------------------------------------------------------
// Dev Server Middleware
const webpackDevMiddleware = require("webpack-dev-middleware");
const webpack = require("webpack");
const compiler = webpack(config);
app.use(webpackDevMiddleware(compiler, {
publicPath: config.output.publicPath
filename: config.output.filename
watchOptions: {
aggregateTimeout: 300
poll: true
}
noInfo: true
quiet: false
lazy: false
stats: true
headers: {
"X-Custom-Header": "yes"
}
}));
------------------------------------------------------------------------
==================================================================
==================================================================
const webpack = require('webpack');
const ComponentPlugin = require('component-webpack-plugin');
module.exports = {
==================================================================
entry: './src/app.js',
entry: {
beep: './beep.js',
boop: './boop.js',
},
entry: {
app: './app.js',
vendor: ['jquery', 'underscore', ...]
},
output: {
filename: 'bundle.js'
},
plugins: [
new webpack.optimize.CommonsChunkPlugin(/* entry= */'vendor', /* filename= */'vendor.bundle.js')
]
<script src='vendor.bundle.js'></script>
<script src='bundle.js'></script>
module.exports = {
entry: {
a: './a',
b: './b'
},
output: {
filename: '[name].js'
},
plugins: [
new webpack.optimize.CommonsChunkPlugin('init.js')
]
}
<script src='init.js'></script>
<script src='a.js'></script>
<script src='b.js'></script>
==================================================================
output: { // './bin/app.bundle.js'
path: './bin',
filename: 'app.bundle.js' // '[name].bundle.js'
=============================
path: path.join(__dirname, 'assets', '[hash]'),
publicPath: 'assets/[hash]/',
filename: 'output.[hash].bundle.js',
chunkFilename: '[id].[hash].bundle.js'
},
output: {
libraryTarget: 'var', // export itself to a global var
library: 'Foo' // name of the global var: 'Foo'
},
externals: {
jquery: 'jQuery' // require('jquery') is external and available on the global var jQuery
}
==================================================================
resolve: {
extensions: ['', '.js', '.coffee'],
fallback: path.join(__dirname, 'node_modules')
},
resolveLoader: {
fallback: path.join(__dirname, 'node_modules')
},
module: {
loaders: [
{
test: /\.js$/,
exclude: /node_modules/,
loader: 'babel-loader?mimetype=image/png'
},
{
test: /\.css$/,
loaders: [
'style-loader?mimetype=image/png',
'css-loader?mimetype=image/png'
]
},
{
test: /\.png$/,
loader: 'url-loader',
query: {
mimetype: 'image/png'
}
},
{
test: /\.jsx?$/,
exclude: /(node_modules|bower_components)/,
loaders: [{
loader: 'babel-loader',
query: {
cacheDirectory: true
}
}
]
},
plugins: [
new webpack.IgnorePlugin(/file\.js$/),
new webpack.optimize.UglifyJsPlugin({
compress: {
warnings: false
},
output: {
comments: false
}
}),
new ComponentPlugin()
]
};
==================================================================
var webpack = require('webpack');
webpack(
{
entry: './main.js',
output: {
filename: 'bundle.js'
}
}
, function(err, stats) {
console.log(err); // => fatal compiler error (rar)
var json = stats.toJson() // => webpack --json
console.log(json.errors); // => array of errors
console.log(json.warnings); // => array of warnings
}
);
==================================================================
var ExtractTextPlugin = require('extract-text-webpack-plugin');
module.exports = {
entry: {
posts: './posts',
post: './post',
about: './about'
},
output: {
filename: '[name].js',
chunkFilename: '[id].js'
},
module: {
loaders: [
{
test: /\.css$/,
loader: ExtractTextPlugin.extract('style-loader', 'css-loader')
},
{
test: /\.less$/,
loader: ExtractTextPlugin.extract('style-loader', 'css-loader!less-loader')
}
]
},
plugins: [
new ExtractTextPlugin('[name].css')
]
}
Output files:
posts.js
posts.css
post.js
post.css
about.js
about.css
Styles in Commons Chunk
// ...
module.exports = {
// ...
plugins: [
new webpack.optimize.CommonsChunkPlugin('commons', 'commons.js'),
new ExtractTextPlugin('[name].css')
]
}
Output files:
commons.js
commons.css
posts.js
posts.css
post.js
post.css
about.js
about.css
==================================================================
var CommonsChunkPlugin = require('webpack/lib/optimize/CommonsChunkPlugin');
module.exports = {
entry: {
p1: './page1',
p2: './page2',
p3: './page3',
ap1: './admin/page1',
ap2: './admin/page2'
},
output: {
filename: '[name].js'
},
plugins: [
new CommonsChunkPlugin('admin-commons.js', ['ap1', 'ap2']),
new CommonsChunkPlugin('commons.js', ['p1', 'p2', 'admin-commons.js'])
]
};
// <script>s required:
// page1.html: commons.js, p1.js
// page2.html: commons.js, p2.js
// page3.html: p3.js
// admin-page1.html: commons.js, admin-commons.js, ap1.js
// admin-page2.html: commons.js, admin-commons.js, ap2.js
Подписаться на:
Сообщения (Atom)