предисловие
Я уже писал статью раньше, маме больше не нужно беспокоиться о том, что я не смогу зайти в вебпак, я продолжу дополнять ее в этот раз. Эта статья по-прежнему написана по интуитивно понятным и простым для понимания правилам. Я надеюсь, что все должны помочь. Если вы не знакомы с webpack, вы можете сначала прочитать предыдущую статьюМама, не нужно больше волноваться, что я не могу упаковать веб-сайт. Ниже мы представим использование веб-пакета от мелкого до глубокого.
То, что вы не знаете, что это значит (не по теме)
import path = require('path');
- path.join
- path.resolve
- __dirname
Path на самом деле является модулем в узле Давайте взглянем на эти общие вещи.
path.join
path.join на самом деле является объединением путей.
const path = require('path');
let str1 = path.join('./path/./', './upload', '/file', '123.jpg');
console.log(str1); // path/upload/file/123.jpg
let str2 = path.join('path', 'upload', 'file', '123.jpg');
console.log(str2); // path/upload/file/123.jpg
После его использования вы получаете сшитый путь
path.resolve
это операция абсолютного пути
let myPath = path.resolve('path1', 'path2', 'a');
console.log(myPath); // E:/workspace/NodeJS/path1/path2/a
В результате получается абсолютный путь Учащиеся, которые не понимают абсолютные и относительные пути, должны проверить соответствующие знания.
На этом часть закончена, далее может быть задействовано использование этих вещей.
__dirname
Используйте переменную __dirname, чтобы получить полный абсолютный путь к каталогу, в котором находится текущий файл модуля.
Поскольку мы можем столкнуться с этими вещами ниже, мы кратко упомянем их. На этом отступление закончилось, теперь мы переходим к основной теме.
разрешить конфигурацию
resolve.extensions
Разрабатываем код проекта на редакторе, но этот дурацкий редактор IDE не очень функционален, а импортируемые файлы каждый раз не имеют суффикса. Если вы используете инструмент формирования шаблонов, вам может быть интересно, что когда мы импортируем файлы js, jsx или vue, мы можем использовать их без добавления суффикса. Но вы написали в файл какой-то менее или дерзкий, и не добавили суффикс, и компиляция прямо сообщила об ошибке. На самом деле это проблема решения.
resolve: {
// Add '.ts' and '.tsx' as resolvable extensions.
extensions: [".ts", ".tsx", ".js", ".json"]
}
Настройка разрешения может указать, как разрешаются модули.
Расширения здесь - это использование суффиксов. По умолчанию здесь используется ts/tsx/js/json. Эти файлы можно импортировать без добавления суффиксов. Вам нужно только добавить суффиксы, которые вы хотите опустить в массиве, чтобы добиться того же Эффект. например следующее
extensions: ['.web.js', '.mjs', '.js', '.json', '.web.jsx', '.jsx', '.less']
Теперь даже если редактор не добавит вам суффикс, вам не нужно добавлять суффикс, не слишком ли это хлопотно.
resolve.alias
Вот псевдоним для создания импорта или запроса, чтобы упростить импорт модулей.
resolve: {
alias: {
Utilities: path.resolve(__dirname, 'src/utilities/'),
Temp: path.resolve(__dirname, 'src/templates/')
}
}
1 файл, который вы ввели на SRC / шаблон, могут быть таким.
import 1 from '../src/template/1';
Теперь вы можете написать так
import 1 from 'Temp/1';
Путь здесь зависит от вашего пути к файлу. Не копируйте это.
Я лично считаю, что эти два пункта используются чаще, для других случаев, пожалуйста, проверьте официальную документацию.
Использование глобальных переменных
Используйте глобальные переменные для замены URL
Пока проект находится в стадии разработки, вы можете получить информацию через следующий интерфейс
http://www.xxx.com/test/v3 + 具体接口
Этот интерфейс размещается на тестовом сервере, но в проекте один раз предполагается использование онлайн-сервера.
http://www.xxx.com/api/v4 + 具体接口
Таким образом, вы придумываете глупую идею, используйте вышеуказанный интерфейс для местного развития или тестирования, а затем изменить его, когда он идет онлайн. Призрак, мы не можем быть настолько шоу. Я предлагаю вам хороший путь.
Используйте плагин DefinePlugin для создания глобальных переменных, чтобы решить эту проблему.
DefinePlugin позволяет создать глобальную константу, которую можно настроить во время компиляции. Давайте создадим глобальную переменную с именем url. Если вы разделите файлы конфигурации веб-пакета для среды разработки и рабочей среды, вы можете написать так
开发环境
plugins: [
new webpack.DefinePlugin({
url: JSON.stringify('http://www.xxx.com/test/v3')
})
]
生产环境
plugins: [
new webpack.DefinePlugin({
url: JSON.stringify('http://www.xxx.com/api/v4')
})
]
Если у вас есть только один файл конфигурации веб-пакета, вы также можете написать его так:
plugins: [
new webpack.DefinePlugin({
url: process.env.NODE_ENV === 'production' ?
JSON.stringify('http://www.xxx.com/api/v4') :
JSON.stringify('http://www.xxx.com/test/v3')
})
// 这里其实涉及到一个问题,就是你在生产环境的时候必须增加命令修改process.
// env.NODE_ENV = production,否则上面的代码是不生效的
// 在package.json的scripts对象中可以使用,使用方法见我上一篇webpack的文章
]
Поскольку переменная должна содержать строковые кавычки, вы можете либо использовать «содержимое вашей переменной», либо использовать форму JSON.stringify («содержимое вашей переменной»).
Теперь адрес вашего интерфейса в проекте можно записать так
`${url}/接口信息` // es6的字符串模板应该都懂吧?
Вы также можете использовать console.log(url), теперь мы решили эту отвратительную проблему.
Но нас ждут более отвратительные проблемы, ха-ха. Действительно раздражает! ! !
Если ваш проект скаффолдится, часто будет eslint.Если eslint не установлен, невозможно использовать эту глобальную переменную.Найдите конфигурационный файл eslint и добавьте следующий код
"globals": {
"go": true
}
Многовходовая упаковка файлов
Зачем настраивать многофайловую упаковку записей
Во многих случаях мы используем популярные фреймворки для веб-разработки, такие как vue и react. После периода разработки тест прошел нормально, и мы готовы построить проект, но размер файла после упаковки составляет 4,5 МБ, что не очень хорошо для ПК или мобильных устройств. Если нас это не волнует, то каждый раз, когда мы меняем версию или какая-то другая ситуация, пользователю нужно перезагружать файл размером 4,5 Мб, даже если вы модифицируете только одну строку кода.
Несколько записей для отдельной упаковки файлов сторонних библиотек
Используйте многовходовые файлы с плагинами для решения этой проблемы
entry: {
vendor: ['react', 'react-dom'],
app: "./src/index.tsx"
}
Здесь мы настраиваем две записи, одна из которых — это приложение, которое является файлом записи, который мы традиционно используем. Поставщик использует массив, а мы отдельно извлекаем react и react-dom для упаковки. Мы принципиально не меняем исходный код этих библиотек.Если мы упакуем их отдельно, даже если мы модифицируем код проекта, код react и react-dom менять не нужно.В это время браузер напрямую читает поставщик. Файлового кэша достаточно, что уменьшает объем каждого загружаемого ресурса и повышает удобство работы пользователя.
Используйте с плагином CommonsChunkPlugin
Простое добавление файла записи не сработает, нам нужно использовать плагин, чтобы удалить файл поставщика из файла приложения.
plugins: [
new webpack.optimize.CommonsChunkPlugin('vendor')
]
Теперь мы разделили файлы поставщика и приложения. Вот простой каштан, и друзья могут настроить его в соответствии со своими потребностями.
Также мы можем упаковать публичные компоненты в отдельный пакет, который здесь повторяться не будем, заинтересованные партнеры могут поэкспериментировать сами.
html-webpack-plugin
На самом деле этот плагин уже был представлен в предыдущей статье, но в этот раз мы поговорим о нем немного конкретнее. Мы используем index.html, сгенерированный скаффолдингом. На самом деле вы не можете найти тег script для импорта файла js. Возможно, вы хотите сделать то же самое. Импортировать его самостоятельно очень проблематично. html-webpack-plugin вам в помощь
plugins: [
// Generates an `index.html` file with the <script> injected.
new HtmlWebpackPlugin({
inject: true, // 这个配置项为true表示自动把打包出来的文件通过自动生成script标签添加到html中
template: index.html, // 模板文件,其实如果没有特殊要求,可以考虑就是用原本的html文件,不再单独创建模板。
minify: { // 压缩的配置,感兴趣的同学意义自己查下意思
removeComments: true,
collapseWhitespace: true,
removeRedundantAttributes: true,
useShortDoctype: true,
removeEmptyAttributes: true,
removeStyleLinkTypeAttributes: true,
keepClosingSlash: true,
minifyJS: true,
minifyCSS: true,
minifyURLs: true,
},
})
]
ваш HTML-файл шаблона выглядит так
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Hello React!</title>
</head>
<body>
<div id="example"></div>
<!-- Main -->
</body>
</html>
Настроив его с помощью html-webpack-plugin выше, он станет таким
<!DOCTYPE html><html><head><meta charset="UTF-8"/><title>Hello React!</title></head><body><div id="example"></div><script type="text/javascript" src="vendor.19786c9df38012fdca96.js"></script><script type="text/javascript" src="app.19786c9df38012fdca96.js"></script></body></html>
На самом деле это то же самое, что вы строите с помощью строительных лесов.
Расскажите о некоторых проблемах, которые возникнут в проекте — использование devServer
Когда мы используем webpack, мы часто используем webpack-dev-server. Он предоставляет нам сервер, чтобы наш проект мог работать на сервере.
historyApiFallback
Теперь проект работает нормально локально, вы смотрите на адресную строку
localhost:8080/#
Лидер сказал #какого черта? Его нужно удалить. Чей URL вы видели с #?
Этот # на самом деле полагается на маршрутизацию хеш-маршрутизации. Это можно удалить. React4 - это использование Broswerrouterter, чтобы заменить Hasthrooter, а Vue может пойти, чтобы проверить его. После удаления # мы используем режим истории H5 для маршрута прыжка.
Вы думали, что это сработает?
Но у начальника новые требования, наша страница не помещается в корневую директорию. URL-адрес выглядит следующим образом: www.xxx.com/xxx.В настоящее время, если вы хотите, чтобы страница нормально использовалась на сервере, вам необходимо добавить базовый тег в index.html.
Вы экспериментировали с уверенностью, и обнаружили, что я стерла, сообщила об ошибке, и даже страница не может быть найдена.
Причина этого в том, что мы не можем найти файл ресурсов по этому пути, и будет сообщено о проблеме 404. В настоящее время мы должны установить
devServer: {
historyApiFallback: true
}
Это нужно для того, чтобы сообщить webpack-dev-серверу, что если файл не найден, он будет указывать на index.html по умолчанию.
В некоторых случаях мы можем начать более одного сервиса. В это время порты часто конфликтуют. Добавьте атрибут порта и измените порт для решения конфликта.
devServer: {
historyApiFallback: true,
port: 1234
}
Теперь адрес становится localhost:1234.
На самом деле существует много элементов конфигурации для devServer.Заинтересованные студенты могут зайти на официальный сайт, чтобы проверить.
Проблема горячей замены Webpack
Горячая замена широко известна как HMR, то есть обновляется только локальное содержимое, которое вы изменяете, без обновления всей страницы, что значительно повышает эффективность разработки. Это можно использовать только во время разработки.Давайте кратко поговорим об использовании. Использование react и vue будет обсуждаться позже.
const webpack = require('webpack');
module.exports = {
entry: {
app: './src/index.js'
},
devServer: {
hot: true
},
plugins: [
new webpack.HotModuleReplacementPlugin()
]
Ниже приведена конфигурация, необходимая для файла index.js (здесь это кажется довольно безвкусным, потому что, если вы не пишете все js вместе, вам придется добавлять это в каждый файл).
+ if (module.hot) {
+ module.hot.accept('./app.js', function() {
+ console.log('Accepting the updated printMe module!');
+ printMe();
+ })
+ }
module.hot.accept принимает два параметра, первый параметр — это измененный файл, а второй — функция, которая будет удалена. Здесь, пока app.js изменен, будет запущен обратный вызов.
В большинстве случаев мы используем react или vue, в этом случае ваш HMR с использованием webpack работать не будет. Потому что он не может сохранить состояние этих кадров.
реагировать и vue предоставить нам решения
- react-hot-loader
- vue-loader
Студенты могутnpmПоищите употребление этих двух вещей, и вы найдете соответствующие употребления.
Эта часть конфигурации веб-пакета будетnpmНайти соответствующий загрузчик, чтобы увидеть, очень просто. Я в основном говорю о том, что меня очень смущало в то время.
В основном я говорю о реакции, то есть о том, как написать наш файл index.js при использовании роутинга и редукса.
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import { AppContainer} from 'react-hot-loader'
import registerServiceWorker from './registerServiceWorker';
import { createStore, applyMiddleware, compose } from 'redux';
import thunk from 'redux-thunk';
import reducers from "./reducer";
import "./index.css";
import App from "./App";
import './style/style';
// redux的配置,可以忽略
const store = createStore(reducers, compose(
applyMiddleware(thunk),
window.devToolsExtension ? window.devToolsExtension() : ()=>{}
));
registerServiceWorker();
使用AppContainer包裹根组件即可
const render = Component => {
ReactDOM.render(
<AppContainer>
<Component store={store}/>
</AppContainer>,
document.getElementById('root')
)
};
render(App);
// App作为内容的根组件,redux和router全部放在里面,只要有内容修改,就调用render函数
if (module.hot) {
module.hot.accept('./App', () => { render(App) })
}
Файл приложения
import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';
import { BrowserRouter, Switch, Route } from 'react-router-dom';
import { Provider } from 'react-redux';
import Second from "./second";
import Third from "./Third";
import Header from "./header";
import First from "./first";
class App extends Component {
render() {
return (
<Provider store={this.props.store}>
<BrowserRouter className="App">
<div>
<Header />
<Switch>
<Route exact path="/" component={First}/>
<Route path="/second" component={Second}/>
<Route path="/third" component={Third}/>
</Switch>
</div>
</BrowserRouter>
</Provider>
);
}
}
export default App;
Сью, теперь, когда вы разрабатываете, вам вообще не нужно обновлять страницу, это очень круто. Где модифицировать, где изменить. Спасибо вам всем