Переведите, это в основном используется для изучения Webpack, исходный адресGitHub.com/Ruan Yifeng/Web P…
Руководство по установке и использованию
Во-первых, глобально установите Webpack и webpack-dev-server.
$ npm i -g webpack webpack-dev-server
Затем клонируйте репозиторий клона Ruan Yifeng.
$ git clone https://github.com/ruanyf/webpack-demos.git
Установить зависимости
$ cd webpack-demos
$ npm install
Теперь перейдите в каталог demo* и запустите их.
$ cd demo01
$ npm run dev
Приведенный выше код не откроет ваш браузер автоматически, вам необходимо получить к нему доступ вручную.http://127.0.0.1:8080
Предисловие: Что такое Webpack
WebPack используется для создания сценария модуля JavaScript, чтобы предоставить интерфейсный инструмент, используемый браузером.
Это похоже на Browserify, но может больше~
$ browserify main.js > bundle.js
# 上下代码作用相同
$ webpack main.js bundle.js
Webpack требует файл с именемwebpack.config.js
Файл конфигурации, этот файл представляет собой модуль CommonJS (модуль)
// webpack.config.js的内容
module.exports = {
entry: './main.js',
output: {
filename: 'bundle.js'
}
};
когда построенwebpack.config.js
Затем вы можете запустить Webpack напрямую без параметров
$ webpack
Ниже приведены некоторые обязательные параметры параметров.
-
webpack
- команда сборки во время разработки -
webpack -p
- Команды сборки при выпуске продукта -
webpack --watch
- Сборки для инкрементной разработки -
webpack -d
- включая исходные карты -
webpack --colors
- сделать вывод сборки лучше
можно настроитьwebpack.config.js
серединаscripts
варианты, как показано ниже
// package.json
{
// ...
"scripts": {
"dev": "webpack-dev-server --devtool eval --progress --colors",
"deploy": "NODE_ENV=production webpack -p"
},
// ...
}
Demo01: Входной файл
Файл входа используется Webpack для его чтения и сборки.bundle.js
Например ниже,main.js
является входным файлом
// main.js
document.write('<h1>Hello World</h1>');
index.html
<html>
<body>
<script type="text/javascript" src="bundle.js"></script>
</body>
</html>
Веб-пакет отwebpack.config.js
строитьbundle.js
// webpack.config.js
module.exports = {
entry: './main.js',
output: {
filename: 'bundle.js'
}
};
Выполните следующую команду и получите доступhttp://127.0.0.1:8080
$ cd demo01
$ npm run dev
Demo02: файлы с несколькими записями
Webpack
Позволяет существовать нескольким файлам ввода, что полезно в многостраничных приложениях, где каждая страница имеет отдельный файл ввода.
// main1.js
document.write('<h1>Hello World</h1>');
// main2.js
document.write('<h2>Hello Webpack</h2>');
index.html
<html>
<body>
<script src="bundle1.js"></script>
<script src="bundle2.js"></script>
</body>
</html>
webpack.config.js
module.exports = {
entry: {
bundle1: './main1.js',
bundle2: './main2.js'
},
output: {
filename: '[name].js'
}
};
Demo03:Babel-loader
Загрузчики — это препроцессоры, которые преобразуют некоторые файлы ресурсов в вашем приложении перед процессом сборки Webpack.
Например, Babel-loader может конвертировать файлы JSX/ES6 в обычные файлы JS, после чего Webpack может начать их сборку. В официальной документации веб-пакета есть список загрузчиков.адрес
main.jsx
это файл JSX
// main.jsx
const React = require('react');
const ReactDOM = require('react-dom');
ReactDOM.render(
<h1>Hello, world!</h1>,
document.querySelector('#wrapper')
);
index.html
<html>
<body>
<div id="wrapper"></div>
<script src="bundle.js"></script>
</body>
</html>
webpack.config.js
module.exports = {
entry: './main.jsx',
output: {
filename: 'bundle.js'
},
module: {
rules: [
{
test: /\.jsx?$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: ['es2015', 'react']
}
}
}
]
}
};
В приведенном выше коде два плагина babel-loader, babel-preset-es2015 и babel-preset-react, необходимы для преобразования ES6 и React (перевод: теперь устарело,Подробности)
Demo04:CSS-loader
Webpack позволяет включать CSS в файлы JS и требует, чтобы CSS-загрузчик обрабатывал эти CSS.
main.js
require('./app.css');
app.css
body {
background-color: blue;
}
index.html
<html>
<head>
<script type="text/javascript" src="bundle.js"></script>
</head>
<body>
<h1>Hello World</h1>
</body>
</html>
webpack.config.js
module.exports = {
entry: './main.js',
output: {
filename: 'bundle.js'
},
module: {
rules:[
{
test: /\.css$/,
use: [ 'style-loader', 'css-loader' ]
},
]
}
};
Уведомление! Файлы CSS должны быть преобразованы с помощью двух загрузчиков. CSS-загрузчик используется для чтения файлов CSS для преобразования, другой Style-загрузчик используется для вставки в HTML<style>
Этикетка.
Затем откройте сервер
$ cd demo04
$ npm run dev
Фактически, Webpack вставляет содержимое файлов CSS прямо вindex.html
<head>
<script type="text/javascript" src="bundle.js"></script>
<style type="text/css">
body {
background-color: blue;
}
</style>
</head>
Demo5: Image loader
Webpack может включать изображения в файлы JS
main.js
var img1 = document.createElement("img");
img1.src = require("./small.png");
document.body.appendChild(img1);
var img2 = document.createElement("img");
img2.src = require("./big.png");
document.body.appendChild(img2);
index.html
<html>
<body>
<script type="text/javascript" src="bundle.js"></script>
</body>
</html>
webpack.config.js
module.exports = {
entry: './main.js',
output: {
filename: 'bundle.js'
},
module: {
rules:[
{
test: /\.(png|jpg)$/,
use: [
{
loader: 'url-loader',
options: {
limit: 8192
}
}
]
}
]
}
};
url-loader
Преобразование файлов изображений в<img>
Тег, если размер изображения составляет 8192 байта, он будет преобразован в URL-адрес данных (перевод: изображение будет закодировано в Base64, что уменьшит количество запросов), в противном случае оно будет преобразовано в обычный URL-адрес файла.
<img src="data:image/png;base64,iVBOR...uQmCC">
<img src="4853ca667a2b8b8844eb2693ac1b2578.png">
Demo06:CSS Module
css-loader?modules
(Параметром запроса являются модули) Можно использовать модуль CSS, модуль CSS обеспечивает локальную область действия CSS в вашем файловом модуле JS, вы также можете использовать:global(selector)
Сделайте CSS глобальным.
index.html
<html>
<body>
<h1 class="h1">Hello World</h1>
<h2 class="h2">Hello Webpack</h2>
<div id="example"></div>
<script src="./bundle.js"></script>
</body>
</html>
app.css
/* local scope */
.h1 {
color:red;
}
/* global scope */
:global(.h2) {
color: blue;
}
main.jsx
var React = require('react');
var ReactDOM = require('react-dom');
var style = require('./app.css');
ReactDOM.render(
<div>
<h1 className={style.h1}>Hello World</h1>
<h2 className="h2">Hello Webpack</h2>
</div>,
document.getElementById('example')
);
webpack.config.js
module.exports = {
entry: './main.jsx',
output: {
filename: 'bundle.js'
},
module: {
rules:[
{
test: /\.js[x]?$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: ['es2015', 'react']
}
}
},
{
test: /\.css$/,
use: [
{
loader: 'style-loader'
},
{
loader: 'css-loader',
options: {
modules: true
}
}
]
}
]
}
};
доступ http://127.0.0.1:8080увидит толькоh1
красный, потому что его CSS имеет локальную область видимости, тогдаh2
Он весь синий, потому что это глобальная область.
Demo07:UglifyJs Plugin
Webpack с системой плагинов для расширения его функций. Например,UglifyJs Plugin, который используется для сжатия кода JS, чтобы уменьшить размер файлов JS.
main.js
var longVariableName = 'Hello';
longVariableName += ' World';
document.write('<h1>' + longVariableName + '</h1>');
index.html
<html>
<body>
<script src="bundle.js"></script>
</body>
</html>
webpack.config.js
var webpack = require('webpack');
var UglifyJsPlugin = require('uglifyjs-webpack-plugin');
module.exports = {
entry: './main.js',
output: {
filename: 'bundle.js'
},
plugins: [
new UglifyJsPlugin()
]
};
После доступа к серверу вы можете увидетьmain.js
Сведен к следующему коду:
var o="Hello";o+=" World",document.write("<h1>"+o+"</h1>")
(перевод: находится вbundle.js
Последние несколько кодов того, вот эти коды)
Demo08: Плагин HTML Webpack и плагин Open Browser Webpack
Эта демонстрация используется для демонстрации того, как загружать сторонние плагины.html-webpack-plugin
может создать для васindex.html
,open-browser-webpack-plugin
Возможность открывать новую вкладку браузера при загрузке Webpack
main.js
document.write('<h1>Hello World</h1>');
webpack.config.js
var HtmlwebpackPlugin = require('html-webpack-plugin');
var OpenBrowserPlugin = require('open-browser-webpack-plugin');
module.exports = {
entry: './main.js',
output: {
filename: 'bundle.js'
},
plugins: [
new HtmlwebpackPlugin({
title: 'Webpack-demos',
filename: 'index.html'
}),
new OpenBrowserPlugin({
url: 'http://localhost:8080'
})
]
};
Теперь вам не нужно вручную создаватьindex.html
Нет необходимости открывать браузер вручную.
Demo09: Флаги среды
Используйте переменные среды, чтобы сделать код только при разработке среды.
main.js
document.write('<h1>Hello World</h1>');
if (__DEV__) {
document.write(new Date());
}
index.html
<html>
<body>
<script src="bundle.js"></script>
</body>
</html>
webpack.config.js
var webpack = require('webpack');
var devFlagPlugin = new webpack.DefinePlugin({
__DEV__: JSON.stringify(JSON.parse(process.env.DEBUG || 'false'))
});
module.exports = {
entry: './main.js',
output: {
filename: 'bundle.js'
},
plugins: [devFlagPlugin]
};
Теперь передайте переменные среды в Webpack. Открытьdemo09/package.json
, находится следующим образомscripts
Опции
// package.json
{
// ...
"scripts": {
"dev": "cross-env DEBUG=true webpack-dev-server --open",
},
// ...
}
Demo10: Разделение кода
В большом веб-приложении помещать весь код в один файл очень неэффективно. Webpack позволяет разбивать большие файлы JS на куски. В частности, некоторые блоки кода загружаются по запросу, если они нужны только в определенных ситуациях.
Webpack используетrequire.ensure
определить точку разделения
// main.js
require.ensure(['./a'], function (require) {
var content = require('./a');
document.open();
document.write('<h1>' + content + '</h1>');
document.close();
});
require.ensure
сказать вебпак./a,js
нужно отbundle.js
выделен в виде отдельного файла фрагмента
// a.js
module.exports = 'Hello World';
Теперь Webpack заботится о зависимостях, выходных файлах, вещах во время выполнения. Вам не нужно класть лишние вещиindex.html
а такжеwebpack.config.js
середина
index.html
<html>
<body>
<script src="bundle.js"></script>
</body>
</html>
webpack.config.js
module.exports = {
entry: './main.js',
output: {
filename: 'bundle.js'
}
};
После доступа к серверу вы не почувствуете никакой разницы. На самом деле, Webpack будет строитьmain.js
а такжеa.js
в другой блок(bundle.js
а также0.bundle.js
), то изbundle.js
нагрузка по требованию0.bundle.js
Demo11: разделение кода в пакетном загрузчике
Еще один способ расщепления кодаbundle-loader
// main.js
// Now a.js is requested, it will be bundled into another file
var load = require('bundle-loader!./a.js');
// To wait until a.js is available (and get the exports)
// you need to async wait for it.
load(function(file) {
document.open();
document.write('<h1>' + file + '</h1>');
document.close();
});
require('bundle-loader!./a.js')
Скажите WebPack нагрузки с других блоковa.js
Сейчасmain.js
построить какbundle.js
,a.js
построить как0.bundle.js
Demo12: Общий блок
В нескольких сценариях JS есть общие блоки, черезCommonsChunkPlugin
Вы можете извлекать общие части из разных файлов, что очень полезно для кэширования браузера для экономии полосы пропускания.
// main1.jsx
var React = require('react');
var ReactDOM = require('react-dom');
ReactDOM.render(
<h1>Hello World</h1>,
document.getElementById('a')
);
// main2.jsx
var React = require('react');
var ReactDOM = require('react-dom');
ReactDOM.render(
<h2>Hello Webpack</h2>,
document.getElementById('b')
);
index.html
<html>
<body>
<div id="a"></div>
<div id="b"></div>
<script src="commons.js"></script>
<script src="bundle1.js"></script>
<script src="bundle2.js"></script>
</body>
</html>
надcommons.js
даmain1.jsx
а такжеmain2.jsx
общая часть. Как ты думаешь,commons.js
включатьreact
а такжеreact-dom
Webpack.config.js
var webpack = require('webpack');
module.exports = {
entry: {
bundle1: './main1.jsx',
bundle2: './main2.jsx'
},
output: {
filename: '[name].js'
},
module: {
rules:[
{
test: /\.js[x]?$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: ['es2015', 'react']
}
}
},
]
},
plugins: [
new webpack.optimize.CommonsChunkPlugin({
name: "commons",
// (the commons chunk name)
filename: "commons.js",
// (the filename of the commons chunk)
})
]
}
Demo13:Vendor chunk
пройти черезCommonsChunkPlugin
, вы можете извлекать официальные библиотеки из JS-скриптов в отдельные файлы
main.js
var $ = require('jquery');
$('h1').text('Hello World');
index.html
<html>
<body>
<h1></h1>
<script src="vendor.js"></script>
<script src="bundle.js"></script>
</body>
</html>
webpack.config.js
var webpack = require('webpack');
module.exports = {
entry: {
app: './main.js',
vendor: ['jquery'],
},
output: {
filename: 'bundle.js'
},
plugins: [
new webpack.optimize.CommonsChunkPlugin({
name: 'vendor',
filename: 'vendor.js'
})
]
};
В приведенном выше кодеentry.vendor:['jquery']
скажи вебпак,jquery
должен быть включен в общий блокvendor.js
середина.
Если вы хотите, чтобы модуль как глобальная переменная использовался в разных модулях, например, не в каждом файлеrequire('jquery')
, но пусть$
илиjQuery
В качестве глобальной переменной вам нужно использоватьProvidePlugin
, который может автоматически загружать модули без необходимости ходить куда угодноimport
илиrequire
// main.js
$('h1').text('Hello World');
// webpack.config.js
var webpack = require('webpack');
module.exports = {
entry: {
app: './main.js'
},
output: {
filename: 'bundle.js'
},
plugins: [
new webpack.ProvidePlugin({
$: 'jquery',
jQuery: 'jquery'
})
]
};
Конечно, в Demo13 вам нужно загрузить его глобально самостоятельно.jquery.js
Демонстрация 14: предоставление глобальных переменных
Если вы хотите использовать некоторые глобальные переменные, не включая их в пакет webpack, вы можете использовать файл webpack.config.jsexternals
поле
Например, у нас естьdata.js
// data.js
var data = 'Hello World';
index.html
<html>
<body>
<script src="data.js"></script>
<script src="bundle.js"></script>
</body>
</html>
Обратите внимание, что Webpack будет собирать толькоbundle.js
, вместо построенияdata.js
мы можем поставитьdata
как глобальная переменная
// webpack.config.js
module.exports = {
entry: './main.jsx',
output: {
filename: 'bundle.js'
},
module: {
rules:[
{
test: /\.js[x]?$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: ['es2015', 'react']
}
}
},
]
},
externals: {
// require('data') is external and available
// on the global var data
'data': 'data'
}
};
В этот момент вы можетеrequire('data')
Как переменная модуля, это на самом деле глобальная переменная
// main.jsx
var data = require('data');
var React = require('react');
var ReactDOM = require('react-dom');
ReactDOM.render(
<h1>{data}</h1>,
document.body
);
так же может бытьreact
а такжеreact-dom
положить вexternals
, что значительно сокращает сборкуbundle.js
время и размер файла
Demo15:React router
В этой демонстрации используется Webpack для создания официального примера маршрутизатора React.
Сначала представьте небольшое приложение с панелью управления, почтовым ящиком, календарем.
+---------------------------------------------------------+
| +---------+ +-------+ +--------+ |
| |Dashboard| | Inbox | |Calendar| Logged in as Jane |
| +---------+ +-------+ +--------+ |
+---------------------------------------------------------+
| |
| Dashboard |
| |
| |
| +---------------------+ +----------------------+ |
| | | | | |
| | + + | +---------> | |
| | | | | | | |
| | | + | | +-------------> | |
| | | | + | | | | |
| | | | | | | | | |
| +-+---+----+-----+----+ +----------------------+ |
| |
+---------------------------------------------------------+
webpack.config.js
module.exports = {
entry: './index.js',
output: {
filename: 'bundle.js'
},
module: {
rules: [
{
test: /\.css$/,
use: [ 'style-loader', 'css-loader' ]
},
{
test: /\.jsx?$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: ['es2015', 'react']
}
}
},
]
}
};
index.js
import React from 'react';
import { render } from 'react-dom';
import { BrowserRouter, Switch, Route, Link } from 'react-router-dom';
import './app.css';
class App extends React.Component {
render() {
return (
<div>
<header>
<ul>
<li><Link to="/app">Dashboard</Link></li>
<li><Link to="/inbox">Inbox</Link></li>
<li><Link to="/calendar">Calendar</Link></li>
</ul>
Logged in as Jane
</header>
<main>
<Switch>
<Route exact path="/" component={Dashboard}/>
<Route path="/app" component={Dashboard}/>
<Route path="/inbox" component={Inbox}/>
<Route path="/calendar" component={Calendar}/>
<Route path="*" component={Dashboard}/>
</Switch>
</main>
</div>
);
}
};
class Dashboard extends React.Component {
render() {
return (
<div>
<p>Dashboard</p>
</div>
);
}
};
class Inbox extends React.Component {
render() {
return (
<div>
<p>Inbox</p>
</div>
);
}
};
class Calendar extends React.Component {
render() {
return (
<div>
<p>Calendar</p>
</div>
);
}
};
render((
<BrowserRouter>
<Route path="/" component={App} />
</BrowserRouter>
), document.querySelector('#app'));
index.html
<html>
<body>
<div id="app"></div>
<script src="/bundle.js"></script>
</body>
</htmL>
затем посетитеhttp://127.0.0.1:8080