#css #angular #typescript #npm #webpack
#css #angular #typescript #npm #webpack
Вопрос:
Допустим, мы начинаем со следующего стартового пакета: https://github.com/angularclass/angular2-webpack-starter
После npm install
и npm run start
все работает нормально.
Я хочу добавить внешний модуль css, например, css bootstrap 4 (и только css). (Я знаю, что в bootstrap есть загрузчик начальной загрузки, но теперь я прошу общего решения, поэтому, пожалуйста, подумайте о bootstrap 4 здесь, поскольку это может быть любой другой модуль css, доступный через npm).
Я устанавливаю bootstrap через npm: npm install bootstrap@4.0.0-alpha.4 --save
Сначала я подумал, что достаточно добавить import 'bootstrap/dist/css/bootstrap.css';
в файл vendor.browser.ts.
Но это не так.
Что я должен сделать, чтобы получить правильное решение?
Решения, о которых я НЕ прошу:
- «Скопируйте внешний модуль css в папку assets и используйте его оттуда»
- Я ищу решение, которое работает вместе с пакетом npm.
- «Использовать загрузчик для webpack»
- Как я описал выше, я ищу общее решение, bootstrap здесь только пример.
- «Использовать другой стек»
- Я ищу решение в точном стартовом пакете, о котором я упоминал выше.
Комментарии:
1. Вы получаете какую-либо ошибку?
2. Это официально лучшая тема SO, в которой я когда-либо участвовал. Звездный вопрос и два столь же звездных ответа. Спасибо всем.
Ответ №1:
Это возможно с помощью @import '~bootstrap/dist/css/bootstrap.css';
файла styles.css. (Обратите внимание на ~)
Редактировать: Как это работает — ‘~’ — это псевдоним, установленный в конфигурации webpack, указывающий на папку assets… все просто..
Редактирование 2: Пример настройки webpack с псевдонимом ‘~’ … это должно быть в файле конфигурации webpack (обычно webpack.config.js
)…
// look for the "resolve" property and add the following...
// you might need to require the asset like '~/bootsrap/...'
resolve: {
alias: {
'~': path.resolve('./node_modules')
}
}
Комментарии:
1. Это сработало для меня, и мне очень нравится идея сохранения моих файлов css, поэтому я не хотел использовать ViewEncapsulation. нет сделки. Но как это работает?
2. Насколько я знаю, это что-то в компиляторе, но поскольку я не эксперт, я оставлю это кому-то, кто знает лучше, чтобы объяснить, как это работает…
3. Я попробовал это, но получил сообщение об ошибке: GET localhost:55490/~bootstrap/css/bootstrap.min.css 404 (Не найден)
4. Для тех, кто хочет понять, как это работает, вот хорошее чтение blog.angularindepth.com /…
5. Раньше это не работало в Angular 6, но работает для Angular 7. Однако я не вижу в журнале изменений ничего, что объясняет, почему. Кто-нибудь знает?
Ответ №2:
Вы не сможете импортировать какой-либо css в свой файл vendors, используя этот стек, без внесения некоторых изменений.
Почему? Ну, потому что эта строка:
import 'bootstrap/dist/css/bootstrap.css';
Это только импорт вашего css в виде строки, когда на самом деле вам нужен css вашего поставщика в теге стиля. Если вы проверите config/webpack.commons.js
, вы найдете это правило:
{
test: /.css$/,
loaders: ['to-string-loader', 'css-loader']
},
Это правило позволяет вашим компонентам импортировать файлы css, в основном это:
@Component({
selector: 'app',
encapsulation: ViewEncapsulation.None,
styleUrls: [
'./app.component.css' // this why you import css as string
],
В AppComponent нет инкапсуляции из-за этой строки encapsulation: ViewEncapsulation.None,
, что означает, что любые правила css будут применяться глобально к вашему приложению. Таким образом, вы можете импортировать стили начальной загрузки в свой компонент приложения:
@Component({
selector: 'app',
encapsulation: ViewEncapsulation.None,
styleUrls: [
'./app.component.css',
'../../node_modules/bootstrap/dist/css/bootstrap.css'
],
Но если вы настаиваете на импорте в свой vendor.ts
, вам нужно будет установить новый загрузчик, npm i style-loader --save-dev
это позволит webpack вводить css на вашу страницу. Затем вам нужно создать конкретное правило на вашем webpack.common.js и измените существующий:
{ //this rule will only be used for any vendors
test: /.css$/,
loaders: ['style-loader', 'css-loader'],
include: [/node_modules/]
},
{
test: /.css$/,
loaders: ['to-string-loader', 'css-loader'],
exclude: [/node_modules/] //add this line so we ignore css coming from node_modules
},
Первое правило будет применяться только при попытке импортировать css из любого пакета внутри node_modules
второе правило будет применяться к любому css, который вы импортируете извне node_modules
Комментарии:
1. Спасибо, чувак, это своего рода идеальный ответ, который я искал. Оба решения работают хорошо. Одна вещь, которую я не знал, это то, что можно настроить таргетинг на node_modules из styleUrls. Это тоже предпочтительная вещь?
2. Нет правильного или неправильного, либо они действительны, но если в будущем вы планируете размещать свой vendor.css в отдельном файле, тогда последний вариант лучше.
3. обратите внимание, что angular2-webpack-starter уже имеет загрузчик стилей в своем package.json (что означает, что для его использования в этом примере не требуется дополнительная установка npm)
4. @Burnee верно, но это бот, который используется где угодно, поэтому они могут удалить его в будущем. Так что оставлю в ответе, на всякий случай, для будущих читателей.
5. Как заставить мое угловое приложение обрабатывать импорт установленной библиотеки
@import "~dist/3rd_party_lib/blabla.css
какnode_modules/dist/3rd_party_lib/blabla.css
, а не какhttps://localhost:4200/~/dist/3rd_party_lib/blabla.css
?
Ответ №3:
Итак, вот способ импортировать различные CSS
файлы, используя тот angular-cli
, который я нахожу наиболее удобным.
В принципе, вы можете ссылаться на CSS
файлы (порядок важен, если вы будете переопределять их) в конфигурации и angular-cli
позаботитесь обо всем остальном. Например, вы можете захотеть включить пару стилей из node-modules, что можно сделать следующим образом:
"styles": [
"../node_modules/font-awesome/css/font-awesome.min.css",
"../node_modules/primeng/resources/primeng.min.css",
"styles.css"
]
Пример полной конфигурации может выглядеть следующим образом:
.angular-cli.json
{
"$schema": "./node_modules/@angular/cli/lib/config/schema.json",
"project": {
"name": "my-angular-app"
},
"apps": [
{
"root": "src",
"outDir": "dist",
"assets": [
"assets",
"favicon.ico"
],
"index": "index.html",
"main": "main.ts",
"polyfills": "polyfills.ts",
"test": "test.ts",
"tsconfig": "tsconfig.app.json",
"testTsconfig": "tsconfig.spec.json",
"prefix": "app",
"styles": [
"../node_modules/font-awesome/css/font-awesome.min.css",
"../node_modules/primeng/resources/primeng.min.css",
"styles.css"
],
"scripts": [],
"environmentSource": "environments/environment.ts",
"environments": {
"dev": "environments/environment.ts",
"prod": "environments/environment.prod.ts"
}
}
],
"e2e": {
"protractor": {
"config": "./protractor.conf.js"
}
},
"lint": [
{
"project": "src/tsconfig.app.json",
"exclude": "**/node_modules/**"
},
{
"project": "src/tsconfig.spec.json",
"exclude": "**/node_modules/**"
},
{
"project": "e2e/tsconfig.e2e.json",
"exclude": "**/node_modules/**"
}
],
"test": {
"karma": {
"config": "./karma.conf.js"
}
},
"defaults": {
"styleExt": "scss",
"component": {}
}
}