У меня есть:
- JS-файлы, которые я хочу связать.
- МЕНЬШЕ файлов, которые я хочу скомпилировать в CSS (преобразование @imports в один пакет).
Я надеялся указать их как два отдельных входа и иметь два отдельных выхода (вероятно, через extract-text-webpack-plugin). Webpack имеет все необходимые плагины / загрузчики для компиляции, но, похоже, ему не нравится разделение.
Я видел примеры, когда люди требовали свои файлы LESS непосредственно из JS, например require('./app.less');
, по единственной причине, кроме указания webpack включить эти файлы в пакет. Это позволяет иметь только одну точку входа, но мне это кажется неправильным - зачем мне требовать МЕНЬШЕ в моем JS, если это не имеет ничего общего с моим JS-кодом?
Я пробовал использовать несколько точек входа, передавая как JS входа, так и основной файл LESS, но при использовании нескольких точек входа webpack генерирует пакет, который не выполняет JS при загрузке - он объединяет все это, но не знает что нужно выполнить при запуске.
Я просто неправильно использую webpack? Должен ли я запускать отдельные экземпляры webpack для этих отдельных модулей? Стоит ли мне вообще использовать webpack для ресурсов, отличных от JS, если я не собираюсь смешивать их с моим JS?
источник
Ответы:
Может быть нет. Webpack определенно ориентирован на js, с неявным предположением, что то, что вы создаете, является js-приложением. Его реализация
require()
позволяет вам рассматривать все как модуль (включая части Sass / LESS, JSON, почти все) и автоматически выполняет управление вашими зависимостями (все, что выrequire
связали, и ничего больше).Люди делают это, потому что они определяют часть своего приложения (например, компонент React, Backbone View) с помощью js. Эта часть приложения имеет соответствующий CSS. В зависимости от какого-либо внешнего ресурса CSS, который создается отдельно и не упоминается напрямую из модуля js, он хрупкий, с ним труднее работать, он может привести к устареванию стилей и т.д. (Sass, что угодно) партиал, который идет с этим js-компонентом, а js-компонент предназначен
require()
для того, чтобы сделать зависимость понятной (для вас и для инструмента сборки, который никогда не создает стили, которые вам не нужны).Я не знаю, можно ли использовать webpack для самостоятельной сборки CSS (когда на файлы CSS нет ссылок из каких-либо js). Я уверен, что вы могли бы что-то связать с плагинами и т. Д., Но не уверен, что это возможно из коробки. Если вы ссылаетесь на файлы CSS из своего js, вы можете легко связать CSS в отдельный файл с помощью плагина Extract Text, как вы говорите.
источник
Отдельный пакет CSS может быть сгенерирован без использования
require('main/less)
в каком-либо из ваших JS, но, как указал Брендан в первой части своего ответа, Webpack не предназначен для глобального пакета CSS, который идет вместе с модульным JS, однако есть несколько вариантов .Первый - добавить дополнительную точку входа для main.less, а затем использовать плагин Extract Text для создания пакета CSS:
var webpack = require('webpack'), ExtractTextPlugin = require("extract-text-webpack-plugin"); module.exports = { entry: { home: [ 'js/common', 'js/homepage' ], style: [ 'styles/main.less' ] }, output: { path: 'dist', filename: "[name].min.js" }, resolve: { extensions: ["", ".js"] }, module: { loaders: [{ test: /\.less$/, loader: ExtractTextPlugin.extract("style", "css", "less") }] }, plugins: [ new ExtractTextPlugin("[name].min.css", { allChunks: true }) ] };
Проблема с этим методом заключается в том, что вы также создаете нежелательный файл JS, а также пакет, в этом примере:
style.js
это просто пустой модуль Webpack.Другой вариант - добавить основной файл less в существующую точку входа Webpack:
var webpack = require('webpack'), ExtractTextPlugin = require("extract-text-webpack-plugin"); module.exports = { entry: { home: [ 'js/common', 'js/homepage', 'styles/main.less' ], }, output: { path: 'dist', filename: "[name].min.js" }, resolve: { extensions: ["", ".js"] }, module: { loaders: [{ test: /\.less$/, loader: ExtractTextPlugin.extract("style", "css", "less") }] }, plugins: [ new ExtractTextPlugin("[name].min.css", { allChunks: true }) ] };
Это идеально, если у вас есть только одна точка входа, но если у вас их больше, то ваша конфигурация Webpack будет выглядеть немного странно, так как вам придется произвольно выбирать, в какую точку входа добавить основной файл less.
источник
Чтобы дополнительно прояснить предыдущий ответ bdmason - кажется, желательной конфигурацией было бы создание пакета JS и CSS для каждой страницы, например:
entry: { Home: ["./path/to/home.js", "./path/to/home.less"], About: ["./path/to/about.js", "./path/to/about.less"] }
А затем используйте
[name]
переключатель:output: { path: "path/to/generated/bundles", filename: "[name].js" }, plugins: new ExtractTextPlugin("[name].css")
Полная конфигурация - с некоторыми дополнениями, не связанными с вопросом (на самом деле мы используем SASS вместо LESS):
var ExtractTextPlugin = require("extract-text-webpack-plugin"); var debug = process.env.NODE_ENV !== "production"; var webpack = require('webpack'); require('babel-polyfill'); module.exports = [{ devtool: debug ? "inline-sourcemap" : null, entry: { Home: ['babel-polyfill', "./home.js","path/to/HomeRootStyle.scss"], SearchResults: ['babel-polyfill', "./searchResults.js","path/to/SearchResultsRootStyle.scss"] }, module: { loaders: [ { test: /\.jsx?$/, exclude: /(node_modules|bower_components)/, loader: 'babel-loader', query: { presets: ['react', 'es2015'], plugins: ['react-html-attrs', 'transform-class-properties', 'transform-decorators-legacy'] } }, { test: /\.scss$/, loader: ExtractTextPlugin.extract("style-loader","css-raw-loader!sass-loader") } ] }, output: { path: "./res/generated", filename: "[name].js" }, plugins: debug ? [new ExtractTextPlugin("[name].css")] : [ new ExtractTextPlugin("[name].css"), new webpack.DefinePlugin({ 'process.env':{ 'NODE_ENV': JSON.stringify('production') } }), new webpack.optimize.UglifyJsPlugin({ compress:{ warnings: true } }) ] } ];
источник
решение webpack 4 с плагином mini-css-extract
команда webpack рекомендует использовать mini-css-extract вместо плагина extract text
это решение позволяет вам создать отдельный блок, содержащий только ваши записи css:
const path = require('path'); const MiniCssExtractPlugin = require('mini-css-extract-plugin'); function recursiveIssuer(m) { if (m.issuer) { return recursiveIssuer(m.issuer); } else if (m.name) { return m.name; } else { return false; } } module.exports = { entry: { foo: path.resolve(__dirname, 'src/foo'), bar: path.resolve(__dirname, 'src/bar'), }, optimization: { splitChunks: { cacheGroups: { fooStyles: { name: 'foo', test: (m, c, entry = 'foo') => m.constructor.name === 'CssModule' && recursiveIssuer(m) === entry, chunks: 'all', enforce: true, }, barStyles: { name: 'bar', test: (m, c, entry = 'bar') => m.constructor.name === 'CssModule' && recursiveIssuer(m) === entry, chunks: 'all', enforce: true, }, }, }, }, plugins: [ new MiniCssExtractPlugin({ filename: '[name].css', }), ], module: { rules: [ { test: /\.css$/, use: [MiniCssExtractPlugin.loader, 'css-loader'], }, ], }, };
Вот более надуманный пример с использованием нескольких записей из одного из моих личных проектов:
const ManifestPlugin = require('webpack-manifest-plugin') const webpack = require('webpack') const path = require('path') const MiniCssExtractPlugin = require('mini-css-extract-plugin') const VENDOR = path.join(__dirname, 'node_modules') const LOCAL_JS = path.join(__dirname, 'app/assets/js') const LOCAL_SCSS = path.join(__dirname, 'app/assets/scss') const BUILD_DIR = path.join(__dirname, 'public/dist') const EXTERNAL = path.join(__dirname, 'public/external') function recursiveIssuer(m) { if (m.issuer) { return recursiveIssuer(m.issuer); } else if (m.name) { return m.name; } else { return false; } } module.exports = { entry: { vendor: [ `${VENDOR}/jquery/dist/jquery.js`, `${VENDOR}/codemirror/lib/codemirror.js`, `${VENDOR}/codemirror/mode/javascript/javascript.js`, `${VENDOR}/codemirror/mode/yaml/yaml.js`, `${VENDOR}/zeroclipboard/dist/ZeroClipboard.js`, ], app: [ `${LOCAL_JS}/utils.js`, `${LOCAL_JS}/editor.js`, `${LOCAL_JS}/clipboard.js`, `${LOCAL_JS}/fixtures.js`, `${LOCAL_JS}/ui.js`, `${LOCAL_JS}/data.js`, `${LOCAL_JS}/application.js`, `${LOCAL_JS}/google.js` ], 'appStyles': [ `${EXTERNAL}/montserrat.css`, `${EXTERNAL}/icons.css`, `${VENDOR}/purecss/pure-min.css`, `${VENDOR}/purecss/grids-core-min.css`, `${VENDOR}/purecss/grids-responsive-min.css`, `${VENDOR}/codemirror/lib/codemirror.css`, `${VENDOR}/codemirror/theme/monokai.css`, ] }, optimization: { splitChunks: { cacheGroups: { appStyles: { name: 'appStyles', test: (m, c, entry = 'appStyles') => m.constructor.name === 'CssModule' && recursiveIssuer(m) === entry, chunks: 'all', enforce: true, }, }, }, }, module: { rules: [ { test: /\.js$/, exclude: /node_modules/, use: [ 'script-loader'], }, { test: /\.(scss|css)$/, use: [ MiniCssExtractPlugin.loader, 'css-loader', ], }, ], }, mode: 'development', resolve: { extensions: ['.js', '.css', '.scss'] }, output: { path: BUILD_DIR, filename: "[name].[chunkhash].js", }, plugins: [ new ManifestPlugin(), new MiniCssExtractPlugin({ filename: '[name].css' }), ] };
Я понимаю, что этот подход не очень модульный, но он должен дать вам основу для построения и является отличной стратегией для внедрения webpack в проекты, где вы не хотите смешивать javascript и css.
Обратной стороной этого подхода является то, что css-loader по-прежнему генерирует дополнительный файл javascript (независимо от того, используете вы его или нет), это предположительно будет исправлено в webpack 5 .
Я не вижу в этом ничего плохого, но в конечном итоге это зависит от вашей терпимости к управлению несколькими системами сборки. Для меня это кажется излишним, поэтому я предпочитаю оставаться в экосистеме webpack.
Для получения дополнительной информации о стратегиях, описанных выше, см. Https://github.com/webpack-contrib/mini-css-extract-plugin#extracting-css-based-on-entry.
источник
Да, это возможно, но, как говорили другие, для этого вам потребуются дополнительные пакеты (см. DevDependencies в package.json). вот пример кода, который я использовал для компиляции моего загрузочного SCSS -> CSS и Bootstrap JS -> JS.
webpack.config.js:
module.exports = { mode: process.env.NODE_ENV === 'production' ? 'production' : 'development', entry: ['./src/app.js', './src/scss/app.scss'], output: { path: path.resolve(__dirname, 'lib/modules/theme/public'), filename: 'js/bootstrap.js' }, module: { rules: [ { test: /\.scss$/, use: [ { loader: 'file-loader', options: { name: 'css/bootstrap.css', } }, { loader: 'extract-loader' }, { loader: 'css-loader?-url' }, { loader: 'postcss-loader' }, { loader: 'sass-loader' } ] } ] } };
дополнительный файл postcss.config.js:
module.exports = { plugins: { 'autoprefixer': {} } }
package.json:
{ "main": "app.js", "scripts": { "build": "webpack", "start": "node app.js" }, "author": "P'unk Avenue", "license": "MIT", "dependencies": { "bootstrap": "^4.1.3", }, "devDependencies": { "autoprefixer": "^9.3.1", "css-loader": "^1.0.1", "exports-loader": "^0.7.0", "extract-loader": "^3.1.0", "file-loader": "^2.0.0", "node-sass": "^4.10.0", "popper.js": "^1.14.6", "postcss-cli": "^6.0.1", "postcss-loader": "^3.0.0", "sass-loader": "^7.1.0", "style-loader": "^0.23.1", "webpack": "^4.26.1", "webpack-cli": "^3.1.2" } }
См. Руководство здесь: https://florianbrinkmann.com/en/4240/sass-webpack
источник
Как уже упоминалось, вы можете использовать плагин.
ExtractTextPlugin
не рекомендуется.Вы можете использовать в настоящее время рекомендованные
MiniCssExtractPlugin
в конфигурации вашего веб-пакета:module.exports = { entry: { home: ['index.js', 'index.less'] }, plugins: [ new MiniCssExtractPlugin({ filename: '[name].css', }), ] }
источник
Вы также можете поместить свои операторы Less require в свой входной JS-файл:
в body.js
// CSS require('css/_variable.scss') require('css/_npm.scss') require('css/_library.scss') require('css/_lib.scss')
Затем в webpack
entry: { body: [ Path.join(__dirname, '/source/assets/javascripts/_body.js') ] }, const extractSass = new ExtractTextPlugin({ filename: 'assets/stylesheets/all.bundle.css', disable: process.env.NODE_ENV === 'development', allChunks: true })
источник